From de3243e1163978ae0b5f7108c715419f69397a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 8 Sep 2022 08:52:19 +0200 Subject: [PATCH 01/48] 157 use filescoped namespaces --- .../CodeGeneratorBase.cs | 193 +++++---- .../Common/ClassCodeGeneratorFactory.cs | 45 +- .../Common/ClassDefinition.cs | 69 ++-- .../Common/InvalidIdentifierException.cs | 11 +- .../Common/Property.cs | 141 ++++--- .../Common/UnsupportedTypeException.cs | 7 +- .../Configuration/CodeGeneratorOptions.cs | 117 +++--- .../DeliveryCodeGenerator.cs | 169 ++++---- .../Class/BaseClassCodeGenerator.cs | 119 +++--- .../Generators/Class/ClassCodeGenerator.cs | 75 ++-- .../Class/DeliveryClassCodeGenerator.cs | 43 +- .../Class/DeliveryClassCodeGeneratorBase.cs | 75 ++-- .../Class/ManagementClassCodeGenerator.cs | 95 +++-- .../Class/PartialClassCodeGenerator.cs | 33 +- .../Generators/GeneralGenerator.cs | 21 +- .../Generators/TypeProviderCodeGenerator.cs | 97 +++-- .../Helpers/ClassDeclarationHelper.cs | 9 +- .../Helpers/DeliveryElementHelper.cs | 45 +- .../Helpers/ManagementElementHelper.cs | 57 ++- .../Helpers/TextHelpers.cs | 67 ++- .../IOutputProvider.cs | 9 +- .../ManagementCodeGenerator.cs | 113 +++-- .../FileSystemOutputProvider.cs | 63 ++- src/Kontent.Ai.ModelGenerator/Program.cs | 109 +++-- .../ServiceCollectionExtensions.cs | 37 +- .../ValidationExtensions.cs | 91 ++--- .../CodeGeneratorTestsBase.cs | 23 +- .../Common/ClassCodeGeneratorFactoryTests.cs | 241 ++++++----- .../Common/ClassDefinitionTests.cs | 161 ++++---- .../Common/PropertyTests.cs | 173 ++++---- .../DeliveryCodeGeneratorTests.cs | 385 +++++++++--------- .../Fixtures/ManagementModelsProvider.cs | 45 +- .../Class/BaseClassCodeGeneratorTests.cs | 69 ++-- .../Class/ClassCodeGeneratorTests.cs | 173 ++++---- .../Class/DeliveryClassCodeGeneratorTests.cs | 145 ++++--- .../ManagementClassCodeGeneratorTests.cs | 207 +++++----- .../Class/PartialClassCodeGeneratorTests.cs | 39 +- .../TypeProviderCodeGeneratorTests.cs | 101 +++-- .../Helpers/DeliveryElementHelperTests.cs | 79 ++-- .../Helpers/ManagementElementHelperTests.cs | 167 ++++---- .../Helpers/TextHelpersTests.cs | 91 ++--- .../ManagementCodeGeneratorTests.cs | 311 +++++++------- .../ProgramTests.cs | 15 +- .../TestHelper.cs | 37 +- .../ValidationExtensionsTests.cs | 197 +++++---- 45 files changed, 2261 insertions(+), 2308 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs index a866f06a..68b93a43 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs @@ -7,136 +7,135 @@ using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Microsoft.Extensions.Options; -namespace Kontent.Ai.ModelGenerator.Core +namespace Kontent.Ai.ModelGenerator.Core; + +public abstract class CodeGeneratorBase { - public abstract class CodeGeneratorBase - { - private string ProjectId => Options.ManagementApi ? Options.ManagementOptions.ProjectId : Options.DeliveryOptions.ProjectId; + private string ProjectId => Options.ManagementApi ? Options.ManagementOptions.ProjectId : Options.DeliveryOptions.ProjectId; + + protected readonly CodeGeneratorOptions Options; + protected readonly IOutputProvider OutputProvider; - protected readonly CodeGeneratorOptions Options; - protected readonly IOutputProvider OutputProvider; + protected string FilenameSuffix => string.IsNullOrEmpty(Options.FileNameSuffix) ? "" : $".{Options.FileNameSuffix}"; + protected string NoContentTypeAvailableMessage => + $@"No content type available for the project ({ProjectId}). Please make sure you have the Delivery API enabled at https://app.kontent.ai/."; - protected string FilenameSuffix => string.IsNullOrEmpty(Options.FileNameSuffix) ? "" : $".{Options.FileNameSuffix}"; - protected string NoContentTypeAvailableMessage => - $@"No content type available for the project ({ProjectId}). Please make sure you have the Delivery API enabled at https://app.kontent.ai/."; + protected CodeGeneratorBase(IOptions options, IOutputProvider outputProvider) + { + Options = options.Value; + OutputProvider = outputProvider; + } - protected CodeGeneratorBase(IOptions options, IOutputProvider outputProvider) + public async Task RunAsync() + { + await GenerateContentTypeModels(); + + if (!string.IsNullOrEmpty(Options.BaseClass)) { - Options = options.Value; - OutputProvider = outputProvider; + await GenerateBaseClass(); } - public async Task RunAsync() - { - await GenerateContentTypeModels(); + return 0; + } - if (!string.IsNullOrEmpty(Options.BaseClass)) - { - await GenerateBaseClass(); - } + protected string GetFileClassName(string className) => $"{className}{FilenameSuffix}"; - return 0; + protected void WriteToOutputProvider(string content, string fileName, bool overwriteExisting) + { + if (string.IsNullOrEmpty(content)) + { + return; } - protected string GetFileClassName(string className) => $"{className}{FilenameSuffix}"; + OutputProvider.Output(content, fileName, overwriteExisting); + Console.WriteLine($"{fileName} class was successfully created."); + } - protected void WriteToOutputProvider(string content, string fileName, bool overwriteExisting) + protected void WriteToOutputProvider(ICollection classCodeGenerators) + { + foreach (var codeGenerator in classCodeGenerators) { - if (string.IsNullOrEmpty(content)) - { - return; - } - - OutputProvider.Output(content, fileName, overwriteExisting); - Console.WriteLine($"{fileName} class was successfully created."); + OutputProvider.Output(codeGenerator.GenerateCode(), codeGenerator.ClassFilename, + codeGenerator.OverwriteExisting); } - protected void WriteToOutputProvider(ICollection classCodeGenerators) - { - foreach (var codeGenerator in classCodeGenerators) - { - OutputProvider.Output(codeGenerator.GenerateCode(), codeGenerator.ClassFilename, - codeGenerator.OverwriteExisting); - } + Console.WriteLine($"{classCodeGenerators.Count} content type models were successfully created."); + } - Console.WriteLine($"{classCodeGenerators.Count} content type models were successfully created."); - } + protected ClassCodeGenerator GetCustomClassCodeGenerator(string contentTypeCodename) + { + var classDefinition = new ClassDefinition(contentTypeCodename); + var classFilename = $"{classDefinition.ClassName}"; - protected ClassCodeGenerator GetCustomClassCodeGenerator(string contentTypeCodename) - { - var classDefinition = new ClassDefinition(contentTypeCodename); - var classFilename = $"{classDefinition.ClassName}"; + return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename, true); + } - return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename, true); - } + protected static void AddProperty(Property property, ref ClassDefinition classDefinition) + { + classDefinition.AddPropertyCodenameConstant(property.Codename); + classDefinition.AddProperty(property); + } + + protected abstract Task> GetClassCodeGenerators(); - protected static void AddProperty(Property property, ref ClassDefinition classDefinition) + protected static void WriteConsoleErrorMessage(Exception exception, string elementCodename, string elementType, string className) + { + switch (exception) { - classDefinition.AddPropertyCodenameConstant(property.Codename); - classDefinition.AddProperty(property); + case InvalidOperationException: + Console.WriteLine($"Warning: Element '{elementCodename}' is already present in Content Type '{className}'."); + break; + case InvalidIdentifierException: + Console.WriteLine($"Warning: Can't create valid C# Identifier from '{elementCodename}'. Skipping element."); + break; + case ArgumentNullException or ArgumentException: + Console.WriteLine($"Warning: Skipping unknown Content Element type '{elementType}'. (Content Type: '{className}', Element Codename: '{elementCodename}')."); + break; + case UnsupportedTypeException: + Console.WriteLine($"Info: Skipping unsupported Content Element type '{elementType}'. (Content Type: '{className}', Element Codename: '{elementCodename}')."); + break; } + } - protected abstract Task> GetClassCodeGenerators(); + protected static void WriteConsoleErrorMessage(string contentTypeCodename) + { + Console.WriteLine($"Warning: Skipping Content Type '{contentTypeCodename}'. Can't create valid C# identifier from its name."); + } - protected static void WriteConsoleErrorMessage(Exception exception, string elementCodename, string elementType, string className) - { - switch (exception) - { - case InvalidOperationException: - Console.WriteLine($"Warning: Element '{elementCodename}' is already present in Content Type '{className}'."); - break; - case InvalidIdentifierException: - Console.WriteLine($"Warning: Can't create valid C# Identifier from '{elementCodename}'. Skipping element."); - break; - case ArgumentNullException or ArgumentException: - Console.WriteLine($"Warning: Skipping unknown Content Element type '{elementType}'. (Content Type: '{className}', Element Codename: '{elementCodename}')."); - break; - case UnsupportedTypeException: - Console.WriteLine($"Info: Skipping unsupported Content Element type '{elementType}'. (Content Type: '{className}', Element Codename: '{elementCodename}')."); - break; - } - } + private async Task GenerateContentTypeModels() + { + var classCodeGenerators = await GetClassCodeGenerators(); - protected static void WriteConsoleErrorMessage(string contentTypeCodename) + if (!classCodeGenerators.Any()) { - Console.WriteLine($"Warning: Skipping Content Type '{contentTypeCodename}'. Can't create valid C# identifier from its name."); + Console.WriteLine(NoContentTypeAvailableMessage); + return; } - private async Task GenerateContentTypeModels() - { - var classCodeGenerators = await GetClassCodeGenerators(); - - if (!classCodeGenerators.Any()) - { - Console.WriteLine(NoContentTypeAvailableMessage); - return; - } + WriteToOutputProvider(classCodeGenerators); + } - WriteToOutputProvider(classCodeGenerators); - } + private async Task GenerateBaseClass() + { + var classCodeGenerators = await GetClassCodeGenerators(); - private async Task GenerateBaseClass() + if (!classCodeGenerators.Any()) { - var classCodeGenerators = await GetClassCodeGenerators(); - - if (!classCodeGenerators.Any()) - { - Console.WriteLine(NoContentTypeAvailableMessage); - return; - } + Console.WriteLine(NoContentTypeAvailableMessage); + return; + } - var baseClassCodeGenerator = new BaseClassCodeGenerator(Options.BaseClass, Options.Namespace); + var baseClassCodeGenerator = new BaseClassCodeGenerator(Options.BaseClass, Options.Namespace); - foreach (var codeGenerator in classCodeGenerators) - { - baseClassCodeGenerator.AddClassNameToExtend(codeGenerator.ClassDefinition.ClassName); - } + foreach (var codeGenerator in classCodeGenerators) + { + baseClassCodeGenerator.AddClassNameToExtend(codeGenerator.ClassDefinition.ClassName); + } - var baseClassCode = baseClassCodeGenerator.GenerateBaseClassCode(); - WriteToOutputProvider(baseClassCode, Options.BaseClass, false); + var baseClassCode = baseClassCodeGenerator.GenerateBaseClassCode(); + WriteToOutputProvider(baseClassCode, Options.BaseClass, false); - var baseClassExtenderCode = baseClassCodeGenerator.GenerateExtenderCode(); - WriteToOutputProvider(baseClassExtenderCode, baseClassCodeGenerator.ExtenderClassName, true); - } + var baseClassExtenderCode = baseClassCodeGenerator.GenerateExtenderCode(); + WriteToOutputProvider(baseClassExtenderCode, baseClassCodeGenerator.ExtenderClassName, true); } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs index 7586e7bb..5069edcf 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs @@ -2,35 +2,34 @@ using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Generators.Class; -namespace Kontent.Ai.ModelGenerator.Core.Common +namespace Kontent.Ai.ModelGenerator.Core.Common; + +public static class ClassCodeGeneratorFactory { - public static class ClassCodeGeneratorFactory + public static ClassCodeGenerator CreateClassCodeGenerator(CodeGeneratorOptions options, ClassDefinition classDefinition, string classFilename, bool customPartial = false) { - public static ClassCodeGenerator CreateClassCodeGenerator(CodeGeneratorOptions options, ClassDefinition classDefinition, string classFilename, bool customPartial = false) + if (options == null) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (classDefinition == null) - { - throw new ArgumentNullException(nameof(classDefinition)); - } + throw new ArgumentNullException(nameof(options)); + } - if (classFilename == null) - { - throw new ArgumentNullException(nameof(classFilename)); - } + if (classDefinition == null) + { + throw new ArgumentNullException(nameof(classDefinition)); + } - if (customPartial) - { - return new PartialClassCodeGenerator(classDefinition, classFilename, options.Namespace); - } + if (classFilename == null) + { + throw new ArgumentNullException(nameof(classFilename)); + } - return options.ManagementApi - ? new ManagementClassCodeGenerator(classDefinition, classFilename, options.Namespace) - : new DeliveryClassCodeGenerator(classDefinition, classFilename, options.Namespace); + if (customPartial) + { + return new PartialClassCodeGenerator(classDefinition, classFilename, options.Namespace); } + + return options.ManagementApi + ? new ManagementClassCodeGenerator(classDefinition, classFilename, options.Namespace) + : new DeliveryClassCodeGenerator(classDefinition, classFilename, options.Namespace); } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs index 638930e7..193c9823 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs @@ -3,53 +3,52 @@ using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.ModelGenerator.Core.Helpers; -namespace Kontent.Ai.ModelGenerator.Core.Common +namespace Kontent.Ai.ModelGenerator.Core.Common; + +public class ClassDefinition { - public class ClassDefinition - { - public List Properties { get; } = new List(); + public List Properties { get; } = new List(); - public List PropertyCodenameConstants { get; } = new List(); + public List PropertyCodenameConstants { get; } = new List(); - public string ClassName => TextHelpers.GetValidPascalCaseIdentifierName(Codename); + public string ClassName => TextHelpers.GetValidPascalCaseIdentifierName(Codename); - public string Codename { get; } + public string Codename { get; } - public ClassDefinition(string codeName) - { - Codename = string.IsNullOrWhiteSpace(codeName) - ? throw new ArgumentException("Class codeName must be a non null and not white space string.", nameof(codeName)) - : codeName; - } + public ClassDefinition(string codeName) + { + Codename = string.IsNullOrWhiteSpace(codeName) + ? throw new ArgumentException("Class codeName must be a non null and not white space string.", nameof(codeName)) + : codeName; + } - public void AddProperty(Property property) + public void AddProperty(Property property) + { + if (PropertyIsAlreadyPresent(property)) { - if (PropertyIsAlreadyPresent(property)) - { - throw new InvalidOperationException($"Property with Identifier '{property.Identifier}' is already included. Can't add two properties with the same Identifier."); - } - - Properties.Add(property); + throw new InvalidOperationException($"Property with Identifier '{property.Identifier}' is already included. Can't add two properties with the same Identifier."); } - public void AddPropertyCodenameConstant(string codeName) - { - if (PropertyCodenameConstants.Contains(codeName)) - { - throw new InvalidOperationException($"Property with code name '{codeName}' is already included. Can't add two members with the same code name."); - } - - PropertyCodenameConstants.Add(codeName); - } + Properties.Add(property); + } - public void AddSystemProperty() + public void AddPropertyCodenameConstant(string codeName) + { + if (PropertyCodenameConstants.Contains(codeName)) { - AddProperty(new Property("system", nameof(IContentItemSystemAttributes))); + throw new InvalidOperationException($"Property with code name '{codeName}' is already included. Can't add two members with the same code name."); } - private bool PropertyIsAlreadyPresent(Property property) - { - return Properties.Exists(e => e.Identifier == property.Identifier); - } + PropertyCodenameConstants.Add(codeName); + } + + public void AddSystemProperty() + { + AddProperty(new Property("system", nameof(IContentItemSystemAttributes))); + } + + private bool PropertyIsAlreadyPresent(Property property) + { + return Properties.Exists(e => e.Identifier == property.Identifier); } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/InvalidIdentifierException.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/InvalidIdentifierException.cs index 88e03eb4..72713a47 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/InvalidIdentifierException.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/InvalidIdentifierException.cs @@ -1,11 +1,10 @@ using System; -namespace Kontent.Ai.ModelGenerator.Core.Common +namespace Kontent.Ai.ModelGenerator.Core.Common; + +public class InvalidIdentifierException : Exception { - public class InvalidIdentifierException : Exception + public InvalidIdentifierException(string message) : base(message) { - public InvalidIdentifierException(string message) : base(message) - { - } } -} \ No newline at end of file +} diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 7a3af1ca..f0ca21df 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -7,93 +7,92 @@ using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Helpers; -namespace Kontent.Ai.ModelGenerator.Core.Common +namespace Kontent.Ai.ModelGenerator.Core.Common; + +public class Property { - public class Property + public const string StructuredSuffix = "(structured)"; + + public string Identifier => TextHelpers.GetValidPascalCaseIdentifierName(Codename); + + public string Codename { get; } + + public string Id { get; } + + /// + /// Returns return type of the property in a string format (e.g.: "string"). + /// + public string TypeName { get; } + + internal static readonly Dictionary DeliverElementTypesDictionary = new Dictionary { - public const string StructuredSuffix = "(structured)"; + { "text", "string" }, + { "rich_text", "string" }, + { "rich_text" + StructuredSuffix, nameof(IRichTextContent)}, + { "number", "decimal?" }, + { "multiple_choice", $"{nameof(IEnumerable)}<{nameof(IMultipleChoiceOption)}>"}, + { "date_time", "DateTime?" }, + { "asset", $"{nameof(IEnumerable)}<{nameof(IAsset)}>" }, + { "modular_content", $"{nameof(IEnumerable)}<{nameof(Object).ToLower(CultureInfo.InvariantCulture)}>" }, + { "taxonomy", $"{nameof(IEnumerable)}<{nameof(ITaxonomyTerm)}>" }, + { "url_slug", "string" }, + { "custom", "string" } + }; - public string Identifier => TextHelpers.GetValidPascalCaseIdentifierName(Codename); + private static readonly Dictionary ManagementElementTypesDictionary = new Dictionary + { + { ElementMetadataType.Text, nameof(TextElement) }, + { ElementMetadataType.RichText, nameof(RichTextElement) }, + { ElementMetadataType.Number, nameof(NumberElement) }, + { ElementMetadataType.MultipleChoice, nameof(MultipleChoiceElement) }, + { ElementMetadataType.DateTime, nameof(DateTimeElement)}, + { ElementMetadataType.Asset, nameof(AssetElement) }, + { ElementMetadataType.LinkedItems, nameof(LinkedItemsElement) }, + { ElementMetadataType.Subpages, nameof(SubpagesElement) }, + { ElementMetadataType.Taxonomy, nameof(TaxonomyElement) }, + { ElementMetadataType.UrlSlug,nameof(UrlSlugElement) }, + { ElementMetadataType.Custom, nameof(CustomElement) } + }; - public string Codename { get; } + public Property(string codename, string typeName, string id = null) + { + Codename = codename; + TypeName = typeName; + Id = id; + } - public string Id { get; } + public static bool IsContentTypeSupported(string elementType) + { + return DeliverElementTypesDictionary.ContainsKey(elementType); + } - /// - /// Returns return type of the property in a string format (e.g.: "string"). - /// - public string TypeName { get; } + public static bool IsContentTypeSupported(ElementMetadataType elementType) + { + return ManagementElementTypesDictionary.ContainsKey(elementType); + } - internal static readonly Dictionary DeliverElementTypesDictionary = new Dictionary - { - { "text", "string" }, - { "rich_text", "string" }, - { "rich_text" + StructuredSuffix, nameof(IRichTextContent)}, - { "number", "decimal?" }, - { "multiple_choice", $"{nameof(IEnumerable)}<{nameof(IMultipleChoiceOption)}>"}, - { "date_time", "DateTime?" }, - { "asset", $"{nameof(IEnumerable)}<{nameof(IAsset)}>" }, - { "modular_content", $"{nameof(IEnumerable)}<{nameof(Object).ToLower(CultureInfo.InvariantCulture)}>" }, - { "taxonomy", $"{nameof(IEnumerable)}<{nameof(ITaxonomyTerm)}>" }, - { "url_slug", "string" }, - { "custom", "string" } - }; - - private static readonly Dictionary ManagementElementTypesDictionary = new Dictionary - { - { ElementMetadataType.Text, nameof(TextElement) }, - { ElementMetadataType.RichText, nameof(RichTextElement) }, - { ElementMetadataType.Number, nameof(NumberElement) }, - { ElementMetadataType.MultipleChoice, nameof(MultipleChoiceElement) }, - { ElementMetadataType.DateTime, nameof(DateTimeElement)}, - { ElementMetadataType.Asset, nameof(AssetElement) }, - { ElementMetadataType.LinkedItems, nameof(LinkedItemsElement) }, - { ElementMetadataType.Subpages, nameof(SubpagesElement) }, - { ElementMetadataType.Taxonomy, nameof(TaxonomyElement) }, - { ElementMetadataType.UrlSlug,nameof(UrlSlugElement) }, - { ElementMetadataType.Custom, nameof(CustomElement) } - }; - - public Property(string codename, string typeName, string id = null) + public static Property FromContentTypeElement(string codename, string elementType) + { + if (IsContentTypeSupported(elementType)) { - Codename = codename; - TypeName = typeName; - Id = id; + return new Property(codename, DeliverElementTypesDictionary[elementType]); } - public static bool IsContentTypeSupported(string elementType) - { - return DeliverElementTypesDictionary.ContainsKey(elementType); - } + throw new ArgumentException($"Unknown Content Type {elementType}", nameof(elementType)); + } - public static bool IsContentTypeSupported(ElementMetadataType elementType) + public static Property FromContentTypeElement(ElementMetadataBase element) + { + if (IsContentTypeSupported(element.Type)) { - return ManagementElementTypesDictionary.ContainsKey(elementType); + return new Property(element.Codename, ManagementElementTypesDictionary[element.Type], element.Id.ToString()); } - public static Property FromContentTypeElement(string codename, string elementType) + if (element.Type == ElementMetadataType.Guidelines) { - if (IsContentTypeSupported(elementType)) - { - return new Property(codename, DeliverElementTypesDictionary[elementType]); - } - - throw new ArgumentException($"Unknown Content Type {elementType}", nameof(elementType)); + throw new UnsupportedTypeException(); } - public static Property FromContentTypeElement(ElementMetadataBase element) - { - if (IsContentTypeSupported(element.Type)) - { - return new Property(element.Codename, ManagementElementTypesDictionary[element.Type], element.Id.ToString()); - } - - if (element.Type == ElementMetadataType.Guidelines) - { - throw new UnsupportedTypeException(); - } - - throw new ArgumentException($"Unknown Content Type {element.Type}", nameof(element)); - } + throw new ArgumentException($"Unknown Content Type {element.Type}", nameof(element)); } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/UnsupportedTypeException.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/UnsupportedTypeException.cs index 93fc7547..d6c9eafc 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/UnsupportedTypeException.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/UnsupportedTypeException.cs @@ -1,8 +1,7 @@ using System; -namespace Kontent.Ai.ModelGenerator.Core.Common +namespace Kontent.Ai.ModelGenerator.Core.Common; + +public class UnsupportedTypeException : Exception { - public class UnsupportedTypeException : Exception - { - } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs index fcfeabe1..2a439d1b 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs @@ -1,64 +1,63 @@ using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Configuration; -namespace Kontent.Ai.ModelGenerator.Core.Configuration -{ - public class CodeGeneratorOptions - { - private const bool DefaultGeneratePartials = true; - private const bool DefaultWithTypeProvider = true; - private const bool DefaultStructuredModel = false; - private const bool DefaultManagementApi = false; - private const string DefaultFileNameSuffix = "Generated"; - - /// - /// Delivery Client configuration. - /// - public DeliveryOptions DeliveryOptions { get; set; } - - /// - /// Management Client configuration. - /// - public ManagementOptions ManagementOptions { get; set; } - - /// - /// Namespace name of the generated classes - /// - public string Namespace { get; set; } - - /// - /// Output directory for the generated files - /// - public string OutputDir { get; set; } - - /// - /// Optionally add suffix to the generated files - /// - public string FileNameSuffix { get; set; } = DefaultFileNameSuffix; +namespace Kontent.Ai.ModelGenerator.Core.Configuration; - /// - /// Optionally generate partial classes for user customization - /// - public bool GeneratePartials { get; set; } = DefaultGeneratePartials; - - /// - /// Indicates whether the CustomTypeProvider class should be generated - /// - public bool WithTypeProvider { get; set; } = DefaultWithTypeProvider; - - /// - /// Indicates whether the classes should be generated with types that represent structured data model - /// - public bool StructuredModel { get; set; } = DefaultStructuredModel; - - /// - /// Indicates whether the classes should be generated for CM API SDK - /// - public bool ManagementApi { get; set; } = DefaultManagementApi; - - /// - /// Indicates whether a base class should be created and all output classes should derive from it using a partial class - /// - public string BaseClass { get; set; } - } +public class CodeGeneratorOptions +{ + private const bool DefaultGeneratePartials = true; + private const bool DefaultWithTypeProvider = true; + private const bool DefaultStructuredModel = false; + private const bool DefaultManagementApi = false; + private const string DefaultFileNameSuffix = "Generated"; + + /// + /// Delivery Client configuration. + /// + public DeliveryOptions DeliveryOptions { get; set; } + + /// + /// Management Client configuration. + /// + public ManagementOptions ManagementOptions { get; set; } + + /// + /// Namespace name of the generated classes + /// + public string Namespace { get; set; } + + /// + /// Output directory for the generated files + /// + public string OutputDir { get; set; } + + /// + /// Optionally add suffix to the generated files + /// + public string FileNameSuffix { get; set; } = DefaultFileNameSuffix; + + /// + /// Optionally generate partial classes for user customization + /// + public bool GeneratePartials { get; set; } = DefaultGeneratePartials; + + /// + /// Indicates whether the CustomTypeProvider class should be generated + /// + public bool WithTypeProvider { get; set; } = DefaultWithTypeProvider; + + /// + /// Indicates whether the classes should be generated with types that represent structured data model + /// + public bool StructuredModel { get; set; } = DefaultStructuredModel; + + /// + /// Indicates whether the classes should be generated for CM API SDK + /// + public bool ManagementApi { get; set; } = DefaultManagementApi; + + /// + /// Indicates whether a base class should be created and all output classes should derive from it using a partial class + /// + public string BaseClass { get; set; } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs index a417f1f9..f06ca5fa 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs @@ -10,122 +10,121 @@ using Kontent.Ai.ModelGenerator.Core.Helpers; using Microsoft.Extensions.Options; -namespace Kontent.Ai.ModelGenerator.Core +namespace Kontent.Ai.ModelGenerator.Core; + +public class DeliveryCodeGenerator : CodeGeneratorBase { - public class DeliveryCodeGenerator : CodeGeneratorBase - { - private readonly IDeliveryClient _deliveryClient; + private readonly IDeliveryClient _deliveryClient; - public DeliveryCodeGenerator(IOptions options, IOutputProvider outputProvider, IDeliveryClient deliveryClient) - : base(options, outputProvider) + public DeliveryCodeGenerator(IOptions options, IOutputProvider outputProvider, IDeliveryClient deliveryClient) + : base(options, outputProvider) + { + if (options.Value.ManagementApi) { - if (options.Value.ManagementApi) - { - throw new InvalidOperationException("Cannot create Delivery models with Management API options."); - } - - _deliveryClient = deliveryClient; + throw new InvalidOperationException("Cannot create Delivery models with Management API options."); } - public new async Task RunAsync() - { - await base.RunAsync(); - - if (Options.WithTypeProvider) - { - await GenerateTypeProvider(); - } + _deliveryClient = deliveryClient; + } - return 0; - } + public new async Task RunAsync() + { + await base.RunAsync(); - protected override async Task> GetClassCodeGenerators() + if (Options.WithTypeProvider) { - var deliveryTypes = (await _deliveryClient.GetTypesAsync()).Types; - - var codeGenerators = new List(); - if (deliveryTypes == null) - { - return codeGenerators; - } + await GenerateTypeProvider(); + } - foreach (var contentType in deliveryTypes) - { - try - { - if (Options.GeneratePartials) - { - codeGenerators.Add(GetCustomClassCodeGenerator(contentType.System.Codename)); - } + return 0; + } - codeGenerators.Add(GetClassCodeGenerator(contentType)); - } - catch (InvalidIdentifierException) - { - WriteConsoleErrorMessage(contentType.System.Codename); - } - } + protected override async Task> GetClassCodeGenerators() + { + var deliveryTypes = (await _deliveryClient.GetTypesAsync()).Types; + var codeGenerators = new List(); + if (deliveryTypes == null) + { return codeGenerators; } - internal ClassCodeGenerator GetClassCodeGenerator(IContentType contentType) + foreach (var contentType in deliveryTypes) { - var classDefinition = new ClassDefinition(contentType.System.Codename); - - foreach (var element in contentType.Elements.Values) + try { - try + if (Options.GeneratePartials) { - var elementType = DeliveryElementHelper.GetElementType(Options, element.Type); - var property = Property.FromContentTypeElement(element.Codename, elementType); - AddProperty(property, ref classDefinition); + codeGenerators.Add(GetCustomClassCodeGenerator(contentType.System.Codename)); } - catch (Exception e) - { - WriteConsoleErrorMessage(e, element.Codename, element.Type, classDefinition.ClassName); - } - } - TryAddSystemProperty(classDefinition); + codeGenerators.Add(GetClassCodeGenerator(contentType)); + } + catch (InvalidIdentifierException) + { + WriteConsoleErrorMessage(contentType.System.Codename); + } + } - var classFilename = GetFileClassName(classDefinition.ClassName); + return codeGenerators; + } - return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename); - } + internal ClassCodeGenerator GetClassCodeGenerator(IContentType contentType) + { + var classDefinition = new ClassDefinition(contentType.System.Codename); - private async Task GenerateTypeProvider() + foreach (var element in contentType.Elements.Values) { - var classCodeGenerators = await GetClassCodeGenerators(); - - if (!classCodeGenerators.Any()) + try { - Console.WriteLine(NoContentTypeAvailableMessage); - return; + var elementType = DeliveryElementHelper.GetElementType(Options, element.Type); + var property = Property.FromContentTypeElement(element.Codename, elementType); + AddProperty(property, ref classDefinition); } - - var typeProviderCodeGenerator = new TypeProviderCodeGenerator(Options.Namespace); - - foreach (var codeGenerator in classCodeGenerators) + catch (Exception e) { - typeProviderCodeGenerator.AddContentType(codeGenerator.ClassDefinition.Codename, codeGenerator.ClassDefinition.ClassName); + WriteConsoleErrorMessage(e, element.Codename, element.Type, classDefinition.ClassName); } + } + + TryAddSystemProperty(classDefinition); + + var classFilename = GetFileClassName(classDefinition.ClassName); + + return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename); + } + + private async Task GenerateTypeProvider() + { + var classCodeGenerators = await GetClassCodeGenerators(); - var typeProviderCode = typeProviderCodeGenerator.GenerateCode(); - WriteToOutputProvider(typeProviderCode, TypeProviderCodeGenerator.ClassName, true); + if (!classCodeGenerators.Any()) + { + Console.WriteLine(NoContentTypeAvailableMessage); + return; } - private static void TryAddSystemProperty(ClassDefinition classDefinition) + var typeProviderCodeGenerator = new TypeProviderCodeGenerator(Options.Namespace); + + foreach (var codeGenerator in classCodeGenerators) { - try - { - classDefinition.AddSystemProperty(); - } - catch (InvalidOperationException) - { - Console.WriteLine( - $"Warning: Can't add 'System' property. It's in collision with existing element in Content Type '{classDefinition.ClassName}'."); - } + typeProviderCodeGenerator.AddContentType(codeGenerator.ClassDefinition.Codename, codeGenerator.ClassDefinition.ClassName); + } + + var typeProviderCode = typeProviderCodeGenerator.GenerateCode(); + WriteToOutputProvider(typeProviderCode, TypeProviderCodeGenerator.ClassName, true); + } + + private static void TryAddSystemProperty(ClassDefinition classDefinition) + { + try + { + classDefinition.AddSystemProperty(); + } + catch (InvalidOperationException) + { + Console.WriteLine( + $"Warning: Can't add 'System' property. It's in collision with existing element in Content Type '{classDefinition.ClassName}'."); } } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs index 8f47c323..0342aa88 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs @@ -7,49 +7,49 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class BaseClassCodeGenerator : GeneralGenerator { - public class BaseClassCodeGenerator : GeneralGenerator - { - /// - /// Collection of classes to extend (HashSet ensures that classes get extended only once) - /// - private readonly ICollection _classesToExtend = new HashSet(); + /// + /// Collection of classes to extend (HashSet ensures that classes get extended only once) + /// + private readonly ICollection _classesToExtend = new HashSet(); - private readonly string _className; + private readonly string _className; - /// - /// The calculated Extender Classname - /// - public string ExtenderClassName => $"{_className}Extender"; + /// + /// The calculated Extender Classname + /// + public string ExtenderClassName => $"{_className}Extender"; - public BaseClassCodeGenerator(string className, string @namespace = ClassCodeGenerator.DefaultNamespace) : base(@namespace) - { - _className = className; - } + public BaseClassCodeGenerator(string className, string @namespace = ClassCodeGenerator.DefaultNamespace) : base(@namespace) + { + _className = className; + } - /// - /// Add string values for classes that should be added as partials so they inherit from the base class - /// - /// - public void AddClassNameToExtend(string className) + /// + /// Add string values for classes that should be added as partials so they inherit from the base class + /// + /// + public void AddClassNameToExtend(string className) + { + if (string.IsNullOrEmpty(className)) { - if (string.IsNullOrEmpty(className)) - { - throw new ArgumentException("Class name must be a non empty string", nameof(className)); - } - - _classesToExtend.Add(className); + throw new ArgumentException("Class name must be a non empty string", nameof(className)); } - /// - /// Creates the base class output - /// - /// - public string GenerateBaseClassCode() - { - var tree = CSharpSyntaxTree.ParseText( -$@"using System; + _classesToExtend.Add(className); + } + + /// + /// Creates the base class output + /// + /// + public string GenerateBaseClassCode() + { + var tree = CSharpSyntaxTree.ParseText( + $@"using System; using Kontent.Ai.Delivery.Abstractions; namespace {Namespace} @@ -60,24 +60,24 @@ public partial class {_className} }} }}"); - var cu = (CompilationUnitSyntax)tree.GetRoot().NormalizeWhitespace(); - cu = cu.WithLeadingTrivia(ClassDescription()); + var cu = (CompilationUnitSyntax)tree.GetRoot().NormalizeWhitespace(); + cu = cu.WithLeadingTrivia(ClassDescription()); - AdhocWorkspace cw = new AdhocWorkspace(); - return Formatter.Format(cu, cw).ToFullString().NormalizeLineEndings(); - } + AdhocWorkspace cw = new AdhocWorkspace(); + return Formatter.Format(cu, cw).ToFullString().NormalizeLineEndings(); + } - /// - /// Creates the extender code that uses partials to make all output classes derive from the base class - /// - public string GenerateExtenderCode() - { - var extenders = _classesToExtend.OrderBy(c => c) - .Select((c) => $"public partial class {c} : {_className} {{ }}") - .Aggregate((p, n) => p + Environment.NewLine + n); + /// + /// Creates the extender code that uses partials to make all output classes derive from the base class + /// + public string GenerateExtenderCode() + { + var extenders = _classesToExtend.OrderBy(c => c) + .Select((c) => $"public partial class {c} : {_className} {{ }}") + .Aggregate((p, n) => p + Environment.NewLine + n); - var tree = CSharpSyntaxTree.ParseText( -$@"using System; + var tree = CSharpSyntaxTree.ParseText( + $@"using System; using Kontent.Ai.Delivery.Abstractions; namespace {Namespace} @@ -87,18 +87,17 @@ namespace {Namespace} {extenders} }}"); - var cu = (CompilationUnitSyntax)tree.GetRoot().NormalizeWhitespace(); - cu = cu.WithLeadingTrivia(ExtenderClassDescription); + var cu = (CompilationUnitSyntax)tree.GetRoot().NormalizeWhitespace(); + cu = cu.WithLeadingTrivia(ExtenderClassDescription); - AdhocWorkspace cw = new AdhocWorkspace(); - return Formatter.Format(cu, cw).ToFullString().NormalizeLineEndings(); - } + AdhocWorkspace cw = new AdhocWorkspace(); + return Formatter.Format(cu, cw).ToFullString().NormalizeLineEndings(); + } - protected override SyntaxTrivia ClassDescription() => - ClassDeclarationHelper.GenerateSyntaxTrivia(@"// You can make changes to this class and it will not get overwritten if it already exists."); + protected override SyntaxTrivia ClassDescription() => + ClassDeclarationHelper.GenerateSyntaxTrivia(@"// You can make changes to this class and it will not get overwritten if it already exists."); - private SyntaxTrivia ExtenderClassDescription => ClassDeclarationHelper.GenerateSyntaxTrivia( -@$"{LostChangesComment} + private SyntaxTrivia ExtenderClassDescription => ClassDeclarationHelper.GenerateSyntaxTrivia( + @$"{LostChangesComment} // For further modifications of the class, create or modify the '{_className}.cs' file with the partial class."); - } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs index dc7cda91..d60309f1 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs @@ -6,59 +6,58 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public abstract class ClassCodeGenerator : GeneralGenerator { - public abstract class ClassCodeGenerator : GeneralGenerator - { - public const string DefaultNamespace = "KontentAiModels"; + public const string DefaultNamespace = "KontentAiModels"; - public ClassDefinition ClassDefinition { get; } + public ClassDefinition ClassDefinition { get; } - public string ClassFilename { get; } + public string ClassFilename { get; } - protected ClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) : base(@namespace) - { - ClassDefinition = classDefinition ?? throw new ArgumentNullException(nameof(classDefinition)); - ClassFilename = string.IsNullOrWhiteSpace(classFilename) ? ClassDefinition.ClassName : classFilename; - } + protected ClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) : base(@namespace) + { + ClassDefinition = classDefinition ?? throw new ArgumentNullException(nameof(classDefinition)); + ClassFilename = string.IsNullOrWhiteSpace(classFilename) ? ClassDefinition.ClassName : classFilename; + } - public bool OverwriteExisting => GetType() != typeof(PartialClassCodeGenerator); + public bool OverwriteExisting => GetType() != typeof(PartialClassCodeGenerator); - public string GenerateCode() - { - var usings = GetApiUsings(); - var classDeclaration = GetClassDeclaration(); + public string GenerateCode() + { + var usings = GetApiUsings(); + var classDeclaration = GetClassDeclaration(); - var compilationUnit = GetCompilationUnit(classDeclaration, usings); + var compilationUnit = GetCompilationUnit(classDeclaration, usings); - var customWorkspace = new AdhocWorkspace(); - return Formatter.Format(compilationUnit, customWorkspace).ToFullString().NormalizeLineEndings(); - } + var customWorkspace = new AdhocWorkspace(); + return Formatter.Format(compilationUnit, customWorkspace).ToFullString().NormalizeLineEndings(); + } - protected abstract UsingDirectiveSyntax[] GetApiUsings(); + protected abstract UsingDirectiveSyntax[] GetApiUsings(); - protected virtual ClassDeclarationSyntax GetClassDeclaration() => SyntaxFactory.ClassDeclaration(ClassDefinition.ClassName) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword)); + protected virtual ClassDeclarationSyntax GetClassDeclaration() => SyntaxFactory.ClassDeclaration(ClassDefinition.ClassName) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword)); - protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.GenerateSyntaxTrivia( -@$"{LostChangesComment} + protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.GenerateSyntaxTrivia( + @$"{LostChangesComment} // For further modifications of the class, create a separate file with the partial class."); - protected static AccessorDeclarationSyntax GetAccessorDeclaration(SyntaxKind kind) => - SyntaxFactory.AccessorDeclaration(kind).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); + protected static AccessorDeclarationSyntax GetAccessorDeclaration(SyntaxKind kind) => + SyntaxFactory.AccessorDeclaration(kind).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); - private CompilationUnitSyntax GetCompilationUnit(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usings) - { - var compilationUnit = SyntaxFactory.CompilationUnit() - .AddUsings(usings) - .AddMembers( - SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(Namespace)) - .AddMembers(classDeclaration)); + private CompilationUnitSyntax GetCompilationUnit(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usings) + { + var compilationUnit = SyntaxFactory.CompilationUnit() + .AddUsings(usings) + .AddMembers( + SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(Namespace)) + .AddMembers(classDeclaration)); - compilationUnit = compilationUnit.WithLeadingTrivia(ClassDescription()); + compilationUnit = compilationUnit.WithLeadingTrivia(ClassDescription()); - return compilationUnit; - } + return compilationUnit; } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs index 89307c5f..d269b9e8 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs @@ -2,33 +2,32 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class DeliveryClassCodeGenerator : DeliveryClassCodeGeneratorBase { - public class DeliveryClassCodeGenerator : DeliveryClassCodeGeneratorBase + public DeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) { - public DeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) - : base(classDefinition, classFilename, @namespace) - { - } + } - protected override ClassDeclarationSyntax GetClassDeclaration() - { - var classDeclaration = base.GetClassDeclaration(); + protected override ClassDeclarationSyntax GetClassDeclaration() + { + var classDeclaration = base.GetClassDeclaration(); - classDeclaration = classDeclaration.AddMembers(ClassCodenameConstant); - classDeclaration = classDeclaration.AddMembers(PropertyCodenameConstants); - classDeclaration = classDeclaration.AddMembers(Properties); + classDeclaration = classDeclaration.AddMembers(ClassCodenameConstant); + classDeclaration = classDeclaration.AddMembers(PropertyCodenameConstants); + classDeclaration = classDeclaration.AddMembers(Properties); - return classDeclaration; - } + return classDeclaration; + } - protected override UsingDirectiveSyntax[] GetApiUsings() => new[] - { - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(nameof(System))), - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(System.Collections.Generic.IEnumerable<>).Namespace!)), - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Delivery.Abstractions.IApiResponse).Namespace!)) - }; + protected override UsingDirectiveSyntax[] GetApiUsings() => new[] + { + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(nameof(System))), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(System.Collections.Generic.IEnumerable<>).Namespace!)), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Delivery.Abstractions.IApiResponse).Namespace!)) + }; - private FieldDeclarationSyntax ClassCodenameConstant => GetFieldDeclaration("string", "Codename", ClassDefinition.Codename); - } + private FieldDeclarationSyntax ClassCodenameConstant => GetFieldDeclaration("string", "Codename", ClassDefinition.Codename); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs index c332a35f..3e20c166 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs @@ -4,48 +4,47 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public abstract class DeliveryClassCodeGeneratorBase : ClassCodeGenerator { - public abstract class DeliveryClassCodeGeneratorBase : ClassCodeGenerator + protected DeliveryClassCodeGeneratorBase(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) { - protected DeliveryClassCodeGeneratorBase(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) - : base(classDefinition, classFilename, @namespace) - { - } + } - protected MemberDeclarationSyntax[] Properties - => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => SyntaxFactory - .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) - .AddAccessorListAccessors( - GetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration), - GetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration) - )).ToArray(); + protected MemberDeclarationSyntax[] Properties + => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => SyntaxFactory + .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .AddAccessorListAccessors( + GetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration), + GetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration) + )).ToArray(); - protected MemberDeclarationSyntax[] PropertyCodenameConstants - => ClassDefinition.PropertyCodenameConstants - .OrderBy(p => p) - .Select(codename => - GetFieldDeclaration("string", $"{TextHelpers.GetValidPascalCaseIdentifierName(codename)}Codename", codename)) - .ToArray(); + protected MemberDeclarationSyntax[] PropertyCodenameConstants + => ClassDefinition.PropertyCodenameConstants + .OrderBy(p => p) + .Select(codename => + GetFieldDeclaration("string", $"{TextHelpers.GetValidPascalCaseIdentifierName(codename)}Codename", codename)) + .ToArray(); - protected static FieldDeclarationSyntax GetFieldDeclaration(string typeName, string identifier, string literal) => - SyntaxFactory.FieldDeclaration( - SyntaxFactory.VariableDeclaration( - SyntaxFactory.ParseTypeName(typeName), - SyntaxFactory.SeparatedList(new[] - { - SyntaxFactory.VariableDeclarator( - SyntaxFactory.Identifier( - identifier), - null, - SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression( - SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(literal))) - ) - }) - ) + protected static FieldDeclarationSyntax GetFieldDeclaration(string typeName, string identifier, string literal) => + SyntaxFactory.FieldDeclaration( + SyntaxFactory.VariableDeclaration( + SyntaxFactory.ParseTypeName(typeName), + SyntaxFactory.SeparatedList(new[] + { + SyntaxFactory.VariableDeclarator( + SyntaxFactory.Identifier( + identifier), + null, + SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression( + SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(literal))) + ) + }) ) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.ConstKeyword)); - } + ) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.ConstKeyword)); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs index 7f311535..1ae34545 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs @@ -5,61 +5,60 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Newtonsoft.Json.Serialization; -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class ManagementClassCodeGenerator : ClassCodeGenerator { - public class ManagementClassCodeGenerator : ClassCodeGenerator + private static readonly string KontentElementIdAttributeName = new string + ( + nameof(KontentElementIdAttribute) + .Substring(0, nameof(KontentElementIdAttribute).Length - "Attribute".Length) + .ToArray() + ); + + public ManagementClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) { - private static readonly string KontentElementIdAttributeName = new string - ( - nameof(KontentElementIdAttribute) - .Substring(0, nameof(KontentElementIdAttribute).Length - "Attribute".Length) - .ToArray() - ); + } - public ManagementClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) - : base(classDefinition, classFilename, @namespace) + protected override UsingDirectiveSyntax[] GetApiUsings() => + new[] { - } - - protected override UsingDirectiveSyntax[] GetApiUsings() => - new[] - { - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Management.Models.LanguageVariants.Elements.BaseElement).Namespace!)), - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(KontentElementIdAttribute).Namespace!)), - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName($"{nameof(Newtonsoft)}.{nameof(Newtonsoft.Json)}")) - }; + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Management.Models.LanguageVariants.Elements.BaseElement).Namespace!)), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(KontentElementIdAttribute).Namespace!)), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName($"{nameof(Newtonsoft)}.{nameof(Newtonsoft.Json)}")) + }; - protected override ClassDeclarationSyntax GetClassDeclaration() - { - var classDeclaration = base.GetClassDeclaration(); + protected override ClassDeclarationSyntax GetClassDeclaration() + { + var classDeclaration = base.GetClassDeclaration(); - classDeclaration = classDeclaration.AddMembers(Properties); + classDeclaration = classDeclaration.AddMembers(Properties); - return classDeclaration; - } + return classDeclaration; + } - private MemberDeclarationSyntax[] Properties => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => - SyntaxFactory - .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) - .AddAccessorListAccessors( - GetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration), - GetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration)) - .AddAttributeLists( - GetAttributeList(nameof(JsonProperty), element.Codename), - GetAttributeList(KontentElementIdAttributeName, element.Id))) - .ToArray(); + private MemberDeclarationSyntax[] Properties => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => + SyntaxFactory + .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .AddAccessorListAccessors( + GetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration), + GetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration)) + .AddAttributeLists( + GetAttributeList(nameof(JsonProperty), element.Codename), + GetAttributeList(KontentElementIdAttributeName, element.Id))) + .ToArray(); - private static AttributeListSyntax GetAttributeList(string identifier, string literal) => - SyntaxFactory.AttributeList( - SyntaxFactory.SingletonSeparatedList( - SyntaxFactory.Attribute(SyntaxFactory.IdentifierName(identifier)) - .WithArgumentList( - SyntaxFactory.AttributeArgumentList( - SyntaxFactory.SingletonSeparatedList( - SyntaxFactory.AttributeArgument( - SyntaxFactory.LiteralExpression( - SyntaxKind.StringLiteralExpression, - SyntaxFactory.Literal(literal)))))))); - } + private static AttributeListSyntax GetAttributeList(string identifier, string literal) => + SyntaxFactory.AttributeList( + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.Attribute(SyntaxFactory.IdentifierName(identifier)) + .WithArgumentList( + SyntaxFactory.AttributeArgumentList( + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.AttributeArgument( + SyntaxFactory.LiteralExpression( + SyntaxKind.StringLiteralExpression, + SyntaxFactory.Literal(literal)))))))); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs index 8d509830..972d6967 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs @@ -4,28 +4,27 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class PartialClassCodeGenerator : DeliveryClassCodeGeneratorBase { - public class PartialClassCodeGenerator : DeliveryClassCodeGeneratorBase + public PartialClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) { - public PartialClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) - : base(classDefinition, classFilename, @namespace) - { - } + } - protected override ClassDeclarationSyntax GetClassDeclaration() - { - var classDeclaration = base.GetClassDeclaration(); + protected override ClassDeclarationSyntax GetClassDeclaration() + { + var classDeclaration = base.GetClassDeclaration(); - classDeclaration = classDeclaration.AddMembers(PropertyCodenameConstants); - classDeclaration = classDeclaration.AddMembers(Properties); + classDeclaration = classDeclaration.AddMembers(PropertyCodenameConstants); + classDeclaration = classDeclaration.AddMembers(Properties); - return classDeclaration; - } + return classDeclaration; + } - protected override UsingDirectiveSyntax[] GetApiUsings() => Array.Empty(); + protected override UsingDirectiveSyntax[] GetApiUsings() => Array.Empty(); - protected override SyntaxTrivia ClassDescription() => - ClassDeclarationHelper.GenerateSyntaxTrivia(@"// Changes to this file will not be lost if the code is regenerated."); - } + protected override SyntaxTrivia ClassDescription() => + ClassDeclarationHelper.GenerateSyntaxTrivia(@"// Changes to this file will not be lost if the code is regenerated."); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/GeneralGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/GeneralGenerator.cs index 2a495b45..0814abd9 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/GeneralGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/GeneralGenerator.cs @@ -1,19 +1,18 @@ using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Microsoft.CodeAnalysis; -namespace Kontent.Ai.ModelGenerator.Core.Generators -{ - public abstract class GeneralGenerator - { - protected const string LostChangesComment = "// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."; +namespace Kontent.Ai.ModelGenerator.Core.Generators; - public readonly string Namespace; +public abstract class GeneralGenerator +{ + protected const string LostChangesComment = "// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."; - protected GeneralGenerator(string @namespace = ClassCodeGenerator.DefaultNamespace) - { - Namespace = string.IsNullOrWhiteSpace(@namespace) ? ClassCodeGenerator.DefaultNamespace : @namespace; - } + public readonly string Namespace; - protected abstract SyntaxTrivia ClassDescription(); + protected GeneralGenerator(string @namespace = ClassCodeGenerator.DefaultNamespace) + { + Namespace = string.IsNullOrWhiteSpace(@namespace) ? ClassCodeGenerator.DefaultNamespace : @namespace; } + + protected abstract SyntaxTrivia ClassDescription(); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/TypeProviderCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/TypeProviderCodeGenerator.cs index 1d4cb959..f890f79f 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/TypeProviderCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/TypeProviderCodeGenerator.cs @@ -10,56 +10,56 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; -namespace Kontent.Ai.ModelGenerator.Core.Generators +namespace Kontent.Ai.ModelGenerator.Core.Generators; + +public class TypeProviderCodeGenerator : GeneralGenerator { - public class TypeProviderCodeGenerator : GeneralGenerator - { - public const string ClassName = "CustomTypeProvider"; + public const string ClassName = "CustomTypeProvider"; + + /// + /// Codename -> ClassName dictionary + /// + private readonly Dictionary _contentTypes = new Dictionary(); - /// - /// Codename -> ClassName dictionary - /// - private readonly Dictionary _contentTypes = new Dictionary(); + public TypeProviderCodeGenerator(string @namespace = ClassCodeGenerator.DefaultNamespace) : base(@namespace) + { + } - public TypeProviderCodeGenerator(string @namespace = ClassCodeGenerator.DefaultNamespace) : base(@namespace) + public void AddContentType(string codename, string className) + { + if (string.IsNullOrEmpty(codename)) { + throw new ArgumentException("Codename must be a non empty string", nameof(codename)); } - public void AddContentType(string codename, string className) + if (string.IsNullOrEmpty(className)) { - if (string.IsNullOrEmpty(codename)) - { - throw new ArgumentException("Codename must be a non empty string", nameof(codename)); - } - - if (string.IsNullOrEmpty(className)) - { - throw new ArgumentException("Class name must be a non empty string", nameof(className)); - } - - _contentTypes[codename] = className; + throw new ArgumentException("Class name must be a non empty string", nameof(className)); } - public string GenerateCode() + _contentTypes[codename] = className; + } + + public string GenerateCode() + { + if (!_contentTypes.Any()) { - if (!_contentTypes.Any()) - { - return null; - } + return null; + } - var cu = (CompilationUnitSyntax)SyntaxTree.GetRoot(); - cu = cu.WithLeadingTrivia(ClassDescription()); + var cu = (CompilationUnitSyntax)SyntaxTree.GetRoot(); + cu = cu.WithLeadingTrivia(ClassDescription()); - AdhocWorkspace cw = new AdhocWorkspace(); - return Formatter.Format(cu, cw).ToFullString().NormalizeLineEndings(); - } + AdhocWorkspace cw = new AdhocWorkspace(); + return Formatter.Format(cu, cw).ToFullString().NormalizeLineEndings(); + } - protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.GenerateSyntaxTrivia( -@"// Changes to this file will not be lost if the code is regenerated. + protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.GenerateSyntaxTrivia( + @"// Changes to this file will not be lost if the code is regenerated. // It will maintain an up-to-date list of the Content types available"); - private SyntaxTree SyntaxTree => CSharpSyntaxTree.ParseText( -$@"using System; + private SyntaxTree SyntaxTree => CSharpSyntaxTree.ParseText( + $@"using System; using System.Collections.Generic; using System.Linq; using {typeof(ITypeProvider).Namespace}; @@ -85,22 +85,21 @@ public virtual string GetCodename(Type contentType) }} }}"); - private string CreateCodenameDictionaryValues() - { - if (_contentTypes.Count == 0) return null; + private string CreateCodenameDictionaryValues() + { + if (_contentTypes.Count == 0) return null; - var dictionaryValuesBuilder = new StringBuilder(); + var dictionaryValuesBuilder = new StringBuilder(); - foreach (var entry in _contentTypes.Take(_contentTypes.Count - 1)) - { - dictionaryValuesBuilder.AppendLine($"\t\t\t{{typeof({entry.Value}), \"{entry.Key}\"}},"); - } + foreach (var entry in _contentTypes.Take(_contentTypes.Count - 1)) + { + dictionaryValuesBuilder.AppendLine($"\t\t\t{{typeof({entry.Value}), \"{entry.Key}\"}},"); + } - var lastEntry = _contentTypes.Last(); - dictionaryValuesBuilder - .Append($"\t\t\t{{typeof({lastEntry.Value}), \"{lastEntry.Key}\"}}"); + var lastEntry = _contentTypes.Last(); + dictionaryValuesBuilder + .Append($"\t\t\t{{typeof({lastEntry.Value}), \"{lastEntry.Key}\"}}"); - return dictionaryValuesBuilder.ToString(); - } + return dictionaryValuesBuilder.ToString(); } -} \ No newline at end of file +} diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/ClassDeclarationHelper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/ClassDeclarationHelper.cs index d9599f68..23c1fcda 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/ClassDeclarationHelper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/ClassDeclarationHelper.cs @@ -1,10 +1,9 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -namespace Kontent.Ai.ModelGenerator.Core.Helpers +namespace Kontent.Ai.ModelGenerator.Core.Helpers; + +internal static class ClassDeclarationHelper { - internal static class ClassDeclarationHelper - { - public static SyntaxTrivia GenerateSyntaxTrivia(string customComment) => SyntaxFactory.Comment(TextHelpers.GenerateCommentString(customComment)); - } + public static SyntaxTrivia GenerateSyntaxTrivia(string customComment) => SyntaxFactory.Comment(TextHelpers.GenerateCommentString(customComment)); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs index ac065921..ce9b0700 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs @@ -2,38 +2,37 @@ using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Configuration; -namespace Kontent.Ai.ModelGenerator.Core.Helpers +namespace Kontent.Ai.ModelGenerator.Core.Helpers; + +public static class DeliveryElementHelper { - public static class DeliveryElementHelper + public static string GetElementType(CodeGeneratorOptions options, string elementType) { - public static string GetElementType(CodeGeneratorOptions options, string elementType) + Validate(options, elementType); + + if (options.StructuredModel && Property.IsContentTypeSupported(elementType + Property.StructuredSuffix)) { - Validate(options, elementType); + elementType += Property.StructuredSuffix; + } - if (options.StructuredModel && Property.IsContentTypeSupported(elementType + Property.StructuredSuffix)) - { - elementType += Property.StructuredSuffix; - } + return elementType; + } - return elementType; + private static void Validate(CodeGeneratorOptions options, string elementType) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); } - private static void Validate(CodeGeneratorOptions options, string elementType) + if (options.ManagementApi) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (options.ManagementApi) - { - throw new InvalidOperationException("Cannot generate structured model for the Management models."); - } + throw new InvalidOperationException("Cannot generate structured model for the Management models."); + } - if (elementType == null) - { - throw new ArgumentNullException(nameof(elementType)); - } + if (elementType == null) + { + throw new ArgumentNullException(nameof(elementType)); } } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/ManagementElementHelper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/ManagementElementHelper.cs index fa1d3051..39530033 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/ManagementElementHelper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/ManagementElementHelper.cs @@ -1,48 +1,45 @@ using System; using System.Collections.Generic; using System.Linq; -using Kontent.Ai.Delivery.Abstractions; -using Kontent.Ai.Management.Models.Types; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.Management.Models.TypeSnippets; -namespace Kontent.Ai.ModelGenerator.Core.Helpers +namespace Kontent.Ai.ModelGenerator.Core.Helpers; + +public static class ManagementElementHelper { - public static class ManagementElementHelper + public static IEnumerable GetManagementContentTypeSnippetElements( + ElementMetadataBase element, + IEnumerable managementSnippets) { - public static IEnumerable GetManagementContentTypeSnippetElements( - ElementMetadataBase element, - IEnumerable managementSnippets) + Validate(element, managementSnippets); + + if (element.Type != ElementMetadataType.ContentTypeSnippet) { - Validate(element, managementSnippets); + return null; + } - if (element.Type != ElementMetadataType.ContentTypeSnippet) - { - return null; - } + var managementSnippet = managementSnippets.FirstOrDefault(s => element.Codename == s.Codename); + if (managementSnippet == null) + { + throw new ArgumentException($"{nameof(managementSnippet)} shouldn't be null."); + } - var managementSnippet = managementSnippets.FirstOrDefault(s => element.Codename == s.Codename); - if (managementSnippet == null) - { - throw new ArgumentException($"{nameof(managementSnippet)} shouldn't be null."); - } + return managementSnippet.Elements; + } - return managementSnippet.Elements; + private static void Validate( + ElementMetadataBase element, + IEnumerable managementSnippets) + { + if (element == null) + { + throw new ArgumentNullException(nameof(element)); } - private static void Validate( - ElementMetadataBase element, - IEnumerable managementSnippets) + if (managementSnippets == null) { - if (element == null) - { - throw new ArgumentNullException(nameof(element)); - } - - if (managementSnippets == null) - { - throw new ArgumentNullException(nameof(managementSnippets)); - } + throw new ArgumentNullException(nameof(managementSnippets)); } } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs index b11a51e3..21a67ea7 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs @@ -3,54 +3,53 @@ using System.Text.RegularExpressions; using Kontent.Ai.ModelGenerator.Core.Common; -namespace Kontent.Ai.ModelGenerator.Core.Helpers +namespace Kontent.Ai.ModelGenerator.Core.Helpers; + +public static class TextHelpers { - public static class TextHelpers + private static readonly Regex LineEndings = new Regex(@"\r\n|\n\r|\n|\r"); + private const string WordSeparator = " "; + + /// + /// Returns a valid CSharp Identifier in a Pascal Case format for given string. + /// + public static string GetValidPascalCaseIdentifierName(string name) { - private static readonly Regex LineEndings = new Regex(@"\r\n|\n\r|\n|\r"); - private const string WordSeparator = " "; + string sanitizedName = Regex.Replace(name, "[^a-zA-Z0-9]", WordSeparator, RegexOptions.IgnoreCase | RegexOptions.Multiline); - /// - /// Returns a valid CSharp Identifier in a Pascal Case format for given string. - /// - public static string GetValidPascalCaseIdentifierName(string name) - { - string sanitizedName = Regex.Replace(name, "[^a-zA-Z0-9]", WordSeparator, RegexOptions.IgnoreCase | RegexOptions.Multiline); + // Remove leading numbers and leading whitespace (e.g.: ' 123Name123' -> 'Name123' + sanitizedName = Regex.Replace(sanitizedName, "^(\\s|[0-9])+", ""); - // Remove leading numbers and leading whitespace (e.g.: ' 123Name123' -> 'Name123' - sanitizedName = Regex.Replace(sanitizedName, "^(\\s|[0-9])+", ""); + if (sanitizedName == string.Empty) + { + throw new InvalidIdentifierException($"Unable to create a valid Identifier from '{name}'"); + } - if (sanitizedName == string.Empty) - { - throw new InvalidIdentifierException($"Unable to create a valid Identifier from '{name}'"); - } + return sanitizedName + .ToLower() + .Split(new[] { WordSeparator }, StringSplitOptions.RemoveEmptyEntries) + .Select(word => char.ToUpper(word[0]) + word.Substring(1)) + .Aggregate((previous, current) => previous + current); + } - return sanitizedName - .ToLower() - .Split(new[] { WordSeparator }, StringSplitOptions.RemoveEmptyEntries) - .Select(word => char.ToUpper(word[0]) + word.Substring(1)) - .Aggregate((previous, current) => previous + current); - } + public static string NormalizeLineEndings(this string text) + { + return LineEndings.Replace(text, Environment.NewLine); + } - public static string NormalizeLineEndings(this string text) + public static string GenerateCommentString(string customComment) + { + if (string.IsNullOrWhiteSpace(customComment)) { - return LineEndings.Replace(text, Environment.NewLine); + throw new ArgumentNullException(nameof(customComment)); } - public static string GenerateCommentString(string customComment) - { - if (string.IsNullOrWhiteSpace(customComment)) - { - throw new ArgumentNullException(nameof(customComment)); - } - - return -@$"// + return + @$"// // This code was generated by a kontent-generators-net tool // (see https://github.com/kontent-ai/model-generator-net). // {customComment} // {Environment.NewLine}{Environment.NewLine}"; - } } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/IOutputProvider.cs b/src/Kontent.Ai.ModelGenerator.Core/IOutputProvider.cs index 300dec16..53f864d3 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/IOutputProvider.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/IOutputProvider.cs @@ -1,7 +1,6 @@ -namespace Kontent.Ai.ModelGenerator.Core +namespace Kontent.Ai.ModelGenerator.Core; + +public interface IOutputProvider { - public interface IOutputProvider - { - void Output(string content, string fileName, bool overwriteExisting); - } + void Output(string content, string fileName, bool overwriteExisting); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/ManagementCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/ManagementCodeGenerator.cs index d1b549fd..53bb0bfa 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/ManagementCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/ManagementCodeGenerator.cs @@ -13,84 +13,83 @@ using Kontent.Ai.ModelGenerator.Core.Helpers; using Microsoft.Extensions.Options; -namespace Kontent.Ai.ModelGenerator.Core +namespace Kontent.Ai.ModelGenerator.Core; + +public class ManagementCodeGenerator : CodeGeneratorBase { - public class ManagementCodeGenerator : CodeGeneratorBase - { - private readonly IManagementClient _managementClient; + private readonly IManagementClient _managementClient; - public ManagementCodeGenerator(IOptions options, IOutputProvider outputProvider, IManagementClient managementClient) - : base(options, outputProvider) + public ManagementCodeGenerator(IOptions options, IOutputProvider outputProvider, IManagementClient managementClient) + : base(options, outputProvider) + { + if (!options.Value.ManagementApi) { - if (!options.Value.ManagementApi) - { - throw new InvalidOperationException("Cannot create Management models with Delivery API options."); - } - - _managementClient = managementClient; + throw new InvalidOperationException("Cannot create Management models with Delivery API options."); } - protected override async Task> GetClassCodeGenerators() - { - var managementTypes = await _managementClient.ListContentTypesAsync().GetAllAsync(); - var managementSnippets = await _managementClient.ListContentTypeSnippetsAsync().GetAllAsync(); + _managementClient = managementClient; + } - var codeGenerators = new List(); - if (managementTypes == null || !managementTypes.Any()) - { - return codeGenerators; - } + protected override async Task> GetClassCodeGenerators() + { + var managementTypes = await _managementClient.ListContentTypesAsync().GetAllAsync(); + var managementSnippets = await _managementClient.ListContentTypeSnippetsAsync().GetAllAsync(); - foreach (var contentType in managementTypes) - { - try - { - if (Options.GeneratePartials) - { - codeGenerators.Add(GetCustomClassCodeGenerator(contentType.Codename)); - } + var codeGenerators = new List(); + if (managementTypes == null || !managementTypes.Any()) + { + return codeGenerators; + } - codeGenerators.Add(GetClassCodeGenerator(contentType, managementSnippets)); - } - catch (InvalidIdentifierException) + foreach (var contentType in managementTypes) + { + try + { + if (Options.GeneratePartials) { - WriteConsoleErrorMessage(contentType.Codename); + codeGenerators.Add(GetCustomClassCodeGenerator(contentType.Codename)); } - } - return codeGenerators; + codeGenerators.Add(GetClassCodeGenerator(contentType, managementSnippets)); + } + catch (InvalidIdentifierException) + { + WriteConsoleErrorMessage(contentType.Codename); + } } - internal ClassCodeGenerator GetClassCodeGenerator(ContentTypeModel contentType, IEnumerable managementSnippets) - { - var classDefinition = new ClassDefinition(contentType.Codename); + return codeGenerators; + } - foreach (var element in contentType.Elements) + internal ClassCodeGenerator GetClassCodeGenerator(ContentTypeModel contentType, IEnumerable managementSnippets) + { + var classDefinition = new ClassDefinition(contentType.Codename); + + foreach (var element in contentType.Elements) + { + try { - try + if (element.Type != ElementMetadataType.ContentTypeSnippet) { - if (element.Type != ElementMetadataType.ContentTypeSnippet) - { - AddProperty(Property.FromContentTypeElement(element), ref classDefinition); - } - else - { - var snippetElements = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, managementSnippets); - foreach (var snippetElement in snippetElements) - { - AddProperty(Property.FromContentTypeElement(snippetElement), ref classDefinition); - } - } + AddProperty(Property.FromContentTypeElement(element), ref classDefinition); } - catch (Exception e) + else { - WriteConsoleErrorMessage(e, element.Codename, element.Type.ToString(), classDefinition.ClassName); + var snippetElements = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, managementSnippets); + foreach (var snippetElement in snippetElements) + { + AddProperty(Property.FromContentTypeElement(snippetElement), ref classDefinition); + } } } + catch (Exception e) + { + WriteConsoleErrorMessage(e, element.Codename, element.Type.ToString(), classDefinition.ClassName); + } + } - var classFilename = GetFileClassName(classDefinition.ClassName); + var classFilename = GetFileClassName(classDefinition.ClassName); - return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename); - } + return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename); } } diff --git a/src/Kontent.Ai.ModelGenerator/FileSystemOutputProvider.cs b/src/Kontent.Ai.ModelGenerator/FileSystemOutputProvider.cs index 35cde1fb..e6712e92 100644 --- a/src/Kontent.Ai.ModelGenerator/FileSystemOutputProvider.cs +++ b/src/Kontent.Ai.ModelGenerator/FileSystemOutputProvider.cs @@ -3,47 +3,46 @@ using Kontent.Ai.ModelGenerator.Core.Configuration; using Microsoft.Extensions.Options; -namespace Kontent.Ai.ModelGenerator +namespace Kontent.Ai.ModelGenerator; + +public class FileSystemOutputProvider : IOutputProvider { - public class FileSystemOutputProvider : IOutputProvider - { - private readonly IOptions _options; + private readonly IOptions _options; - internal string OutputDir + internal string OutputDir + { + get { - get - { - var outputDir = _options.Value.OutputDir; + var outputDir = _options.Value.OutputDir; - // Setting OutputDir default value here instead of in the method as it would overwrite the JSON value. - if (string.IsNullOrEmpty(outputDir)) - { - outputDir = "./"; - } + // Setting OutputDir default value here instead of in the method as it would overwrite the JSON value. + if (string.IsNullOrEmpty(outputDir)) + { + outputDir = "./"; + } - // Resolve relative path to full path - outputDir = Path.GetFullPath(outputDir); + // Resolve relative path to full path + outputDir = Path.GetFullPath(outputDir); - return outputDir; - } + return outputDir; } + } - public FileSystemOutputProvider(IOptions options) - { - _options = options; - } + public FileSystemOutputProvider(IOptions options) + { + _options = options; + } - public void Output(string content, string fileName, bool overwriteExisting) - { - // Make sure the output dir exists - Directory.CreateDirectory(OutputDir); + public void Output(string content, string fileName, bool overwriteExisting) + { + // Make sure the output dir exists + Directory.CreateDirectory(OutputDir); - string outputPath = Path.Combine(OutputDir, $"{fileName}.cs"); - bool fileExists = File.Exists(outputPath); - if (!fileExists || overwriteExisting) - { - File.WriteAllText(outputPath, content); - } + string outputPath = Path.Combine(OutputDir, $"{fileName}.cs"); + bool fileExists = File.Exists(outputPath); + if (!fileExists || overwriteExisting) + { + File.WriteAllText(outputPath, content); } } -} \ No newline at end of file +} diff --git a/src/Kontent.Ai.ModelGenerator/Program.cs b/src/Kontent.Ai.ModelGenerator/Program.cs index 652a052f..c9bea69a 100644 --- a/src/Kontent.Ai.ModelGenerator/Program.cs +++ b/src/Kontent.Ai.ModelGenerator/Program.cs @@ -9,75 +9,74 @@ using Kontent.Ai.ModelGenerator.Core; using Kontent.Ai.ModelGenerator.Core.Configuration; -namespace Kontent.Ai.ModelGenerator +namespace Kontent.Ai.ModelGenerator; + +internal class Program { - internal class Program + public static async Task Main(string[] args) { - public static async Task Main(string[] args) + try { - try - { - // Create an instance of a DI container - var services = new ServiceCollection(); + // Create an instance of a DI container + var services = new ServiceCollection(); - if (!ArgHelpers.ContainsValidArgs(args)) - { - await WriteErrorMessageAsync("Failed to run due to invalid configuration."); - return 1; - } + if (!ArgHelpers.ContainsValidArgs(args)) + { + await WriteErrorMessageAsync("Failed to run due to invalid configuration."); + return 1; + } - // Build a configuration object from given sources - var configuration = new ConfigurationBuilder() - .SetBasePath(Environment.CurrentDirectory) - .AddJsonFile("appSettings.json", true) - .AddCommandLine(args, ArgHelpers.GetSwitchMappings(args)) - .Build(); + // Build a configuration object from given sources + var configuration = new ConfigurationBuilder() + .SetBasePath(Environment.CurrentDirectory) + .AddJsonFile("appSettings.json", true) + .AddCommandLine(args, ArgHelpers.GetSwitchMappings(args)) + .Build(); - // Fill the DI container - services.Configure(configuration); - services.AddManagementClient(configuration); - services.AddDeliveryClient(configuration); - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); - services.AddSingleton(); + // Fill the DI container + services.Configure(configuration); + services.AddManagementClient(configuration); + services.AddDeliveryClient(configuration); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(); + services.AddSingleton(); - // Build the DI container - var serviceProvider = services.BuildServiceProvider(); + // Build the DI container + var serviceProvider = services.BuildServiceProvider(); - // Validate configuration of the Delivery Client - var options = serviceProvider.GetService>().Value; - options.Validate(); + // Validate configuration of the Delivery Client + var options = serviceProvider.GetService>().Value; + options.Validate(); - PrintSdkVersion(options); + PrintSdkVersion(options); - // Code generator entry point - return options.ManagementApi - ? await serviceProvider.GetService().RunAsync() - : await serviceProvider.GetService().RunAsync(); - } - catch (AggregateException aex) - { - if ((aex.InnerExceptions.Count == 1) && aex.InnerException is DeliveryException) - { - // Return a friendlier message - await WriteErrorMessageAsync(aex.InnerException.Message); - } - return 1; - } - catch (Exception ex) + // Code generator entry point + return options.ManagementApi + ? await serviceProvider.GetService().RunAsync() + : await serviceProvider.GetService().RunAsync(); + } + catch (AggregateException aex) + { + if ((aex.InnerExceptions.Count == 1) && aex.InnerException is DeliveryException) { - await WriteErrorMessageAsync(ex.Message); - return 1; + // Return a friendlier message + await WriteErrorMessageAsync(aex.InnerException.Message); } + return 1; } - - private static async Task WriteErrorMessageAsync(string message) => await Console.Error.WriteLineAsync(message); - - private static void PrintSdkVersion(CodeGeneratorOptions options) + catch (Exception ex) { - var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(options.ManagementApi); - Console.WriteLine($"Models were generated for {usedSdkInfo.Name} version {usedSdkInfo.Version}"); + await WriteErrorMessageAsync(ex.Message); + return 1; } } + + private static async Task WriteErrorMessageAsync(string message) => await Console.Error.WriteLineAsync(message); + + private static void PrintSdkVersion(CodeGeneratorOptions options) + { + var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(options.ManagementApi); + Console.WriteLine($"Models were generated for {usedSdkInfo.Name} version {usedSdkInfo.Version}"); + } } diff --git a/src/Kontent.Ai.ModelGenerator/ServiceCollectionExtensions.cs b/src/Kontent.Ai.ModelGenerator/ServiceCollectionExtensions.cs index c4ae9081..39a7887f 100644 --- a/src/Kontent.Ai.ModelGenerator/ServiceCollectionExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator/ServiceCollectionExtensions.cs @@ -3,28 +3,27 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -namespace Kontent.Ai.ModelGenerator +namespace Kontent.Ai.ModelGenerator; + +internal static class ServiceCollectionExtensions { - internal static class ServiceCollectionExtensions - { - public static IServiceCollection AddManagementClient(this IServiceCollection services, IConfiguration configuration, string configurationSectionName = "ManagementOptions") - => services - .LoadOptionsConfiguration(configuration, configurationSectionName) - .RegisterDependencies(); + public static IServiceCollection AddManagementClient(this IServiceCollection services, IConfiguration configuration, string configurationSectionName = "ManagementOptions") + => services + .LoadOptionsConfiguration(configuration, configurationSectionName) + .RegisterDependencies(); - private static IServiceCollection RegisterDependencies(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } + private static IServiceCollection RegisterDependencies(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } - private static IServiceCollection LoadOptionsConfiguration(this IServiceCollection services, IConfiguration configuration, string configurationSectionName) - { - var managementOptions = new ManagementOptions(); - configuration.GetSection(configurationSectionName).Bind(managementOptions); - services.AddSingleton(managementOptions); + private static IServiceCollection LoadOptionsConfiguration(this IServiceCollection services, IConfiguration configuration, string configurationSectionName) + { + var managementOptions = new ManagementOptions(); + configuration.GetSection(configurationSectionName).Bind(managementOptions); + services.AddSingleton(managementOptions); - return services; - } + return services; } } diff --git a/src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs b/src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs index ddf62e91..3380a659 100644 --- a/src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs @@ -4,64 +4,63 @@ using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; -namespace Kontent.Ai.ModelGenerator +namespace Kontent.Ai.ModelGenerator; + +/// +/// Extension methods meant for validation. +/// +public static class ValidationExtensions { + private const string DeliveryParamsLink = "http://bit.ly/k-params"; + private const string ManagementParamsLink = "https://bit.ly/3rSMeDA"; + private static string SeePart(bool managementApi) => $"See {(managementApi ? ManagementParamsLink : DeliveryParamsLink)} for more details on configuration."; + /// - /// Extension methods meant for validation. + /// Validates that CodeGeneratorOptions are initialized and performs some extra integrity validations. /// - public static class ValidationExtensions + /// CodeGeneratorOptions object to be validated + public static void Validate(this CodeGeneratorOptions codeGeneratorOptions) { - private const string DeliveryParamsLink = "http://bit.ly/k-params"; - private const string ManagementParamsLink = "https://bit.ly/3rSMeDA"; - private static string SeePart(bool managementApi) => $"See {(managementApi ? ManagementParamsLink : DeliveryParamsLink)} for more details on configuration."; - - /// - /// Validates that CodeGeneratorOptions are initialized and performs some extra integrity validations. - /// - /// CodeGeneratorOptions object to be validated - public static void Validate(this CodeGeneratorOptions codeGeneratorOptions) + if (codeGeneratorOptions.ManagementApi) { - if (codeGeneratorOptions.ManagementApi) - { - codeGeneratorOptions.ManagementOptions.Validate(); - } - else - { - codeGeneratorOptions.DeliveryOptions.Validate(); - } + codeGeneratorOptions.ManagementOptions.Validate(); } - - /// - /// Validates that ManagementOptions are initialized - /// - /// ManagementOptions object to be validated - /// - private static void Validate(this ManagementOptions managementOptions) + else { - var seePart = SeePart(true); - if (managementOptions?.ProjectId == null) - { - throw new Exception($"You have to provide the '{nameof(ManagementOptions.ProjectId)}' to generate type for Management SDK. {seePart}"); - } + codeGeneratorOptions.DeliveryOptions.Validate(); + } + } - if (string.IsNullOrWhiteSpace(managementOptions.ApiKey)) - { - throw new Exception($"You have to provide the '{nameof(ManagementOptions.ApiKey)}' to generate type for Management SDK. {seePart}"); - } + /// + /// Validates that ManagementOptions are initialized + /// + /// ManagementOptions object to be validated + /// + private static void Validate(this ManagementOptions managementOptions) + { + var seePart = SeePart(true); + if (managementOptions?.ProjectId == null) + { + throw new Exception($"You have to provide the '{nameof(ManagementOptions.ProjectId)}' to generate type for Management SDK. {seePart}"); } - /// - /// Validates that DeliveryOptions are initialized and performs some extra integrity validations. - /// - /// DeliveryOptions object to be validated - private static void Validate(this DeliveryOptions deliveryOptions) + if (string.IsNullOrWhiteSpace(managementOptions.ApiKey)) { - if (deliveryOptions == null) - { - throw new Exception($"You have to provide at least the '{nameof(DeliveryOptions.ProjectId)}' argument. {SeePart(false)}"); - } + throw new Exception($"You have to provide the '{nameof(ManagementOptions.ApiKey)}' to generate type for Management SDK. {seePart}"); + } + } - DeliveryOptionsValidator.Validate(deliveryOptions); + /// + /// Validates that DeliveryOptions are initialized and performs some extra integrity validations. + /// + /// DeliveryOptions object to be validated + private static void Validate(this DeliveryOptions deliveryOptions) + { + if (deliveryOptions == null) + { + throw new Exception($"You have to provide at least the '{nameof(DeliveryOptions.ProjectId)}' argument. {SeePart(false)}"); } + + DeliveryOptionsValidator.Validate(deliveryOptions); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs b/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs index 76cd0830..2e03c030 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs @@ -1,20 +1,19 @@ using System.IO; -namespace Kontent.Ai.ModelGenerator.Tests +namespace Kontent.Ai.ModelGenerator.Tests; + +public abstract class CodeGeneratorTestsBase { - public abstract class CodeGeneratorTestsBase - { - protected abstract string TempDir { get; } - protected const string ProjectId = "975bf280-fd91-488c-994c-2f04416e5ee3"; + protected abstract string TempDir { get; } + protected const string ProjectId = "975bf280-fd91-488c-994c-2f04416e5ee3"; - protected CodeGeneratorTestsBase() + protected CodeGeneratorTestsBase() + { + // Cleanup + if (Directory.Exists(TempDir)) { - // Cleanup - if (Directory.Exists(TempDir)) - { - Directory.Delete(TempDir, true); - } - Directory.CreateDirectory(TempDir); + Directory.Delete(TempDir, true); } + Directory.CreateDirectory(TempDir); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs index cc1a819a..4fd733d6 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs @@ -4,150 +4,149 @@ using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Common +namespace Kontent.Ai.ModelGenerator.Tests.Common; + +public class ClassCodeGeneratorFactoryTests { - public class ClassCodeGeneratorFactoryTests + [Fact] + public void CreateClassCodeGenerator_CodeGeneratorOptionsIsNull_ThrowsException() { - [Fact] - public void CreateClassCodeGenerator_CodeGeneratorOptionsIsNull_ThrowsException() - { - Assert.Throws(() => - ClassCodeGeneratorFactory.CreateClassCodeGenerator(null, new ClassDefinition("codename"), "classFileName")); - } + Assert.Throws(() => + ClassCodeGeneratorFactory.CreateClassCodeGenerator(null, new ClassDefinition("codename"), "classFileName")); + } - [Fact] - public void CreateClassCodeGenerator_ClassDefinitionIsNull_ThrowsException() - { - Assert.Throws(() => - ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), null, "classFileName")); - } + [Fact] + public void CreateClassCodeGenerator_ClassDefinitionIsNull_ThrowsException() + { + Assert.Throws(() => + ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), null, "classFileName")); + } - [Fact] - public void CreateClassCodeGenerator_ClassFilenameIsNull_ThrowsException() - { - Assert.Throws(() => - ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), new ClassDefinition("codename"), null)); - } + [Fact] + public void CreateClassCodeGenerator_ClassFilenameIsNull_ThrowsException() + { + Assert.Throws(() => + ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), new ClassDefinition("codename"), null)); + } - [Fact] - public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_NoCustomPartialPropertyFalse_Returns() + [Fact] + public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_NoCustomPartialPropertyFalse_Returns() + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var codeGeneratorOptions = new CodeGeneratorOptions { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = false - }; + ManagementApi = false + }; - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName, false); + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName, false); - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); - } + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); + } - [Fact] - public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_NoCustomPartialProperty_Returns() - { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = false - }; - - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); - - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void CreateClassCodeGenerator_PartialClassCodeGenerator_Returns(bool managementApi) + [Fact] + public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_NoCustomPartialProperty_Returns() + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var codeGeneratorOptions = new CodeGeneratorOptions { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = managementApi - }; + ManagementApi = false + }; - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName, true); + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); - } + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); + } - [Fact] - public void CreateClassCodeGenerator_PartialClassCodeGenerator_CustomNamespace_Returns() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void CreateClassCodeGenerator_PartialClassCodeGenerator_Returns(bool managementApi) + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var codeGeneratorOptions = new CodeGeneratorOptions { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var customNamespace = "CustomNameSpace"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = false, - Namespace = customNamespace - }; - - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName, true); - - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); - } - - [Fact] - public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_CustomNamespace_Returns() + ManagementApi = managementApi + }; + + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName, true); + + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); + } + + [Fact] + public void CreateClassCodeGenerator_PartialClassCodeGenerator_CustomNamespace_Returns() + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var customNamespace = "CustomNameSpace"; + var codeGeneratorOptions = new CodeGeneratorOptions { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var customNamespace = "CustomNameSpace"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = false, - Namespace = customNamespace - }; - - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); - - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); - } - - [Fact] - public void CreateClassCodeGenerator_ManagementClassCodeGenerator_NoCustomPartialProperty_Returns() + ManagementApi = false, + Namespace = customNamespace + }; + + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName, true); + + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); + } + + [Fact] + public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_CustomNamespace_Returns() + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var customNamespace = "CustomNameSpace"; + var codeGeneratorOptions = new CodeGeneratorOptions { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = true - }; + ManagementApi = false, + Namespace = customNamespace + }; - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); - } + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); + } - [Fact] - public void CreateClassCodeGenerator_ManagementClassCodeGenerator_CustomNamespace_Returns() + [Fact] + public void CreateClassCodeGenerator_ManagementClassCodeGenerator_NoCustomPartialProperty_Returns() + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var codeGeneratorOptions = new CodeGeneratorOptions { - var classDefinitionCodename = "codename"; - var classFileName = "classFileName"; - var customNamespace = "CustomNameSpace"; - var codeGeneratorOptions = new CodeGeneratorOptions - { - ManagementApi = true, - Namespace = customNamespace - }; + ManagementApi = true + }; - var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); - AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); - } + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); + } - private static void AssertClassCodeGenerator(ClassCodeGenerator result, string classDefinitionCodename, string classFileName, string @namespace) + [Fact] + public void CreateClassCodeGenerator_ManagementClassCodeGenerator_CustomNamespace_Returns() + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var customNamespace = "CustomNameSpace"; + var codeGeneratorOptions = new CodeGeneratorOptions { - Assert.IsType(result); - Assert.Equal(classDefinitionCodename, result.ClassDefinition.Codename); - Assert.Equal(classFileName, result.ClassFilename); - Assert.Equal(@namespace, result.Namespace); - } + ManagementApi = true, + Namespace = customNamespace + }; + + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); + + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); + } + + private static void AssertClassCodeGenerator(ClassCodeGenerator result, string classDefinitionCodename, string classFileName, string @namespace) + { + Assert.IsType(result); + Assert.Equal(classDefinitionCodename, result.ClassDefinition.Codename); + Assert.Equal(classFileName, result.ClassFilename); + Assert.Equal(@namespace, result.Namespace); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassDefinitionTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassDefinitionTests.cs index 00220af3..b39866c0 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassDefinitionTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassDefinitionTests.cs @@ -3,88 +3,87 @@ using Kontent.Ai.ModelGenerator.Core.Common; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Common +namespace Kontent.Ai.ModelGenerator.Tests.Common; + +public class ClassDefinitionTests { - public class ClassDefinitionTests + [Fact] + public void Constructor_SetsClassNameIdentifier() + { + var definition = new ClassDefinition("Article type"); + + Assert.Equal("ArticleType", definition.ClassName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Constructor_CodenameIsNullEmptyOrWhiteSpace_Throws(string codename) + { + Assert.Throws(() => new ClassDefinition(codename)); + } + + [Fact] + public void AddProperty_AddCustomProperty_PropertyIsAdded() + { + var propertyCodename = "element_1"; + var classDefinition = new ClassDefinition("Class name"); + classDefinition.AddProperty(Property.FromContentTypeElement(propertyCodename, "text")); + + Assert.Single(classDefinition.Properties, property => property.Codename == propertyCodename); + } + + [Fact] + public void AddProperty_CustomSystemField_SystemFieldIsReplaced() + { + var classDefinition = new ClassDefinition("Class name"); + + var userDefinedSystemProperty = Property.FromContentTypeElement("system", "text"); + classDefinition.AddProperty(userDefinedSystemProperty); + + Assert.Equal(userDefinedSystemProperty, classDefinition.Properties.First()); + } + + [Fact] + public void AddSystemProperty_SystemPropertyIsAdded() + { + var classDefinition = new ClassDefinition("Class name"); + classDefinition.AddSystemProperty(); + + Assert.Single(classDefinition.Properties, property => property.Codename == "system"); + } + + [Fact] + public void AddPropertyCodenameConstant_PropertyIsAdded() + { + var elementCodename = "element_codename"; + + var classDefinition = new ClassDefinition("Class name"); + classDefinition.AddPropertyCodenameConstant(elementCodename); + + Assert.Single(classDefinition.PropertyCodenameConstants, property => property == elementCodename); + } + + [Fact] + public void AddPropertyCodenameConstant_DuplicatePropertyCodenameConstant_Throws() + { + var elementCodename = "element_codename"; + + var classDefinition = new ClassDefinition("Class name"); + classDefinition.AddPropertyCodenameConstant(elementCodename); + + Assert.Throws(() => classDefinition.AddPropertyCodenameConstant(elementCodename)); + Assert.Single(classDefinition.PropertyCodenameConstants, property => property == elementCodename); + } + + [Fact] + public void AddProperty_DuplicateElementCodenames_Throws() { - [Fact] - public void Constructor_SetsClassNameIdentifier() - { - var definition = new ClassDefinition("Article type"); - - Assert.Equal("ArticleType", definition.ClassName); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public void Constructor_CodenameIsNullEmptyOrWhiteSpace_Throws(string codename) - { - Assert.Throws(() => new ClassDefinition(codename)); - } - - [Fact] - public void AddProperty_AddCustomProperty_PropertyIsAdded() - { - var propertyCodename = "element_1"; - var classDefinition = new ClassDefinition("Class name"); - classDefinition.AddProperty(Property.FromContentTypeElement(propertyCodename, "text")); - - Assert.Single(classDefinition.Properties, property => property.Codename == propertyCodename); - } - - [Fact] - public void AddProperty_CustomSystemField_SystemFieldIsReplaced() - { - var classDefinition = new ClassDefinition("Class name"); - - var userDefinedSystemProperty = Property.FromContentTypeElement("system", "text"); - classDefinition.AddProperty(userDefinedSystemProperty); - - Assert.Equal(userDefinedSystemProperty, classDefinition.Properties.First()); - } - - [Fact] - public void AddSystemProperty_SystemPropertyIsAdded() - { - var classDefinition = new ClassDefinition("Class name"); - classDefinition.AddSystemProperty(); - - Assert.Single(classDefinition.Properties, property => property.Codename == "system"); - } - - [Fact] - public void AddPropertyCodenameConstant_PropertyIsAdded() - { - var elementCodename = "element_codename"; - - var classDefinition = new ClassDefinition("Class name"); - classDefinition.AddPropertyCodenameConstant(elementCodename); - - Assert.Single(classDefinition.PropertyCodenameConstants, property => property == elementCodename); - } - - [Fact] - public void AddPropertyCodenameConstant_DuplicatePropertyCodenameConstant_Throws() - { - var elementCodename = "element_codename"; - - var classDefinition = new ClassDefinition("Class name"); - classDefinition.AddPropertyCodenameConstant(elementCodename); - - Assert.Throws(() => classDefinition.AddPropertyCodenameConstant(elementCodename)); - Assert.Single(classDefinition.PropertyCodenameConstants, property => property == elementCodename); - } - - [Fact] - public void AddProperty_DuplicateElementCodenames_Throws() - { - var classDefinition = new ClassDefinition("Class name"); - classDefinition.AddProperty(Property.FromContentTypeElement("element", "text")); - - Assert.Throws(() => classDefinition.AddProperty(Property.FromContentTypeElement("element", "text"))); - Assert.Single(classDefinition.Properties); - } + var classDefinition = new ClassDefinition("Class name"); + classDefinition.AddProperty(Property.FromContentTypeElement("element", "text")); + + Assert.Throws(() => classDefinition.AddProperty(Property.FromContentTypeElement("element", "text"))); + Assert.Single(classDefinition.Properties); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs index 5deb561b..379683e7 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs @@ -5,104 +5,103 @@ using Kontent.Ai.ModelGenerator.Core.Common; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Common +namespace Kontent.Ai.ModelGenerator.Tests.Common; + +public class PropertyTests { - public class PropertyTests + [Fact] + public void Constructor_MissingIdParam_ObjectIsInitializedWithCorrectValues() { - [Fact] - public void Constructor_MissingIdParam_ObjectIsInitializedWithCorrectValues() - { - var element = new Property("element_codename", "string"); - - Assert.Equal("ElementCodename", element.Identifier); - Assert.Equal("string", element.TypeName); - Assert.Null(element.Id); - } + var element = new Property("element_codename", "string"); - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("id")] - public void Constructor_IdParamPresent_ObjectIsInitializedWithCorrectValues(string id) - { - var element = new Property("element_codename", "string", id); + Assert.Equal("ElementCodename", element.Identifier); + Assert.Equal("string", element.TypeName); + Assert.Null(element.Id); + } - Assert.Equal("ElementCodename", element.Identifier); - Assert.Equal("string", element.TypeName); - Assert.Equal(id, element.Id); - } + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("id")] + public void Constructor_IdParamPresent_ObjectIsInitializedWithCorrectValues(string id) + { + var element = new Property("element_codename", "string", id); - [Theory] - [InlineData("text", "string")] - [InlineData("rich_text", "string")] - [InlineData("rich_text" + Property.StructuredSuffix, "IRichTextContent")] - [InlineData("number", "decimal?")] - [InlineData("multiple_choice", "IEnumerable")] - [InlineData("date_time", "DateTime?")] - [InlineData("asset", "IEnumerable")] - [InlineData("modular_content", "IEnumerable")] - [InlineData("taxonomy", "IEnumerable")] - [InlineData("url_slug", "string")] - [InlineData("custom", "string")] - public void FromContentTypeElement_DeliveryApiModel_Returns(string contentType, string expectedTypeName) - { - var codename = "element_codename"; - var expectedCodename = "ElementCodename"; + Assert.Equal("ElementCodename", element.Identifier); + Assert.Equal("string", element.TypeName); + Assert.Equal(id, element.Id); + } - var element = Property.FromContentTypeElement(codename, contentType); + [Theory] + [InlineData("text", "string")] + [InlineData("rich_text", "string")] + [InlineData("rich_text" + Property.StructuredSuffix, "IRichTextContent")] + [InlineData("number", "decimal?")] + [InlineData("multiple_choice", "IEnumerable")] + [InlineData("date_time", "DateTime?")] + [InlineData("asset", "IEnumerable")] + [InlineData("modular_content", "IEnumerable")] + [InlineData("taxonomy", "IEnumerable")] + [InlineData("url_slug", "string")] + [InlineData("custom", "string")] + public void FromContentTypeElement_DeliveryApiModel_Returns(string contentType, string expectedTypeName) + { + var codename = "element_codename"; + var expectedCodename = "ElementCodename"; - Assert.Equal(expectedCodename, element.Identifier); - Assert.Equal(expectedTypeName, element.TypeName); - } + var element = Property.FromContentTypeElement(codename, contentType); - [Theory, MemberData(nameof(ManagementElements))] - public void FromContentTypeElement_ManagementApiModel_Returns(string expectedTypeName, string expectedCodename, ElementMetadataBase element) - { - var property = Property.FromContentTypeElement(element); + Assert.Equal(expectedCodename, element.Identifier); + Assert.Equal(expectedTypeName, element.TypeName); + } - Assert.Equal(expectedCodename, property.Identifier); - Assert.Equal(expectedTypeName, property.TypeName); - Assert.Equal(element.Id.ToString(), property.Id); - } + [Theory, MemberData(nameof(ManagementElements))] + public void FromContentTypeElement_ManagementApiModel_Returns(string expectedTypeName, string expectedCodename, ElementMetadataBase element) + { + var property = Property.FromContentTypeElement(element); - [Fact] - public void FromContentTypeElement_DeliveryApiModel_InvalidContentTypeElement_Throws() - { - Assert.Throws(() => Property.FromContentTypeElement("codename", "unknown content type")); - } + Assert.Equal(expectedCodename, property.Identifier); + Assert.Equal(expectedTypeName, property.TypeName); + Assert.Equal(element.Id.ToString(), property.Id); + } - [Fact] - public void FromContentTypeElement_ManagementApiModel_GuidelinesElement_Throws() - { - Assert.Throws(() => - Property.FromContentTypeElement(TestHelper.GenerateGuidelinesElement(Guid.NewGuid(), "codename"))); - } + [Fact] + public void FromContentTypeElement_DeliveryApiModel_InvalidContentTypeElement_Throws() + { + Assert.Throws(() => Property.FromContentTypeElement("codename", "unknown content type")); + } - public static IEnumerable ManagementElements => - new List<(string, string, ElementMetadataBase)> - { - ("TextElement", "TextElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "text_element")), - ("RichTextElement","RichTextElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "rich_text_element", ElementMetadataType.RichText)), - ("NumberElement", "NumberElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "number_element", ElementMetadataType.Number)), - ("MultipleChoiceElement","MultipleChoiceElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "multiple_choice_element", ElementMetadataType.MultipleChoice)), - ("DateTimeElement","DateTimeElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "date_time_element", ElementMetadataType.DateTime)), - ("AssetElement", "AssetElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "asset_element", ElementMetadataType.Asset)), - ("LinkedItemsElement", "LinkedItemsElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "linked_items_element", ElementMetadataType.LinkedItems)), - ("SubpagesElement", "SubpagesElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "subpages_element", ElementMetadataType.Subpages)), - ("TaxonomyElement", "TaxonomyElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "taxonomy_element", ElementMetadataType.Taxonomy)), - ("UrlSlugElement", "UrlSlugElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "url_slug_element", ElementMetadataType.UrlSlug)), - ("CustomElement", "CustomElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "custom_element", ElementMetadataType.Custom)) - }.Select(triple => new object[] { triple.Item1, triple.Item2, triple.Item3 }); + [Fact] + public void FromContentTypeElement_ManagementApiModel_GuidelinesElement_Throws() + { + Assert.Throws(() => + Property.FromContentTypeElement(TestHelper.GenerateGuidelinesElement(Guid.NewGuid(), "codename"))); } + + public static IEnumerable ManagementElements => + new List<(string, string, ElementMetadataBase)> + { + ("TextElement", "TextElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "text_element")), + ("RichTextElement","RichTextElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "rich_text_element", ElementMetadataType.RichText)), + ("NumberElement", "NumberElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "number_element", ElementMetadataType.Number)), + ("MultipleChoiceElement","MultipleChoiceElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "multiple_choice_element", ElementMetadataType.MultipleChoice)), + ("DateTimeElement","DateTimeElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "date_time_element", ElementMetadataType.DateTime)), + ("AssetElement", "AssetElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "asset_element", ElementMetadataType.Asset)), + ("LinkedItemsElement", "LinkedItemsElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "linked_items_element", ElementMetadataType.LinkedItems)), + ("SubpagesElement", "SubpagesElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "subpages_element", ElementMetadataType.Subpages)), + ("TaxonomyElement", "TaxonomyElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "taxonomy_element", ElementMetadataType.Taxonomy)), + ("UrlSlugElement", "UrlSlugElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "url_slug_element", ElementMetadataType.UrlSlug)), + ("CustomElement", "CustomElement", + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "custom_element", ElementMetadataType.Custom)) + }.Select(triple => new object[] { triple.Item1, triple.Item2, triple.Item3 }); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs index 0fa4848a..ad0f4d53 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs @@ -13,245 +13,244 @@ using RichardSzalay.MockHttp; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests +namespace Kontent.Ai.ModelGenerator.Tests; + +public class DeliveryCodeGeneratorTests : CodeGeneratorTestsBase { - public class DeliveryCodeGeneratorTests : CodeGeneratorTestsBase + /// + /// represents count of elements in 'delivery_types.json' + /// + private const int NumberOfContentTypes = 13; + protected override string TempDir => Path.Combine(Path.GetTempPath(), "DeliveryCodeGeneratorIntegrationTests"); + + [Fact] + public void Constructor_ManagementIsTrue_Throws() { - /// - /// represents count of elements in 'delivery_types.json' - /// - private const int NumberOfContentTypes = 13; - protected override string TempDir => Path.Combine(Path.GetTempPath(), "DeliveryCodeGeneratorIntegrationTests"); - - [Fact] - public void Constructor_ManagementIsTrue_Throws() + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { - var mockOptions = new Mock>(); - mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions - { - ManagementApi = true - }); + ManagementApi = true + }); - var deliveryClient = new Mock(); - var outputProvider = new Mock(); + var deliveryClient = new Mock(); + var outputProvider = new Mock(); - Assert.Throws(() => new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object)); - } + Assert.Throws(() => new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object)); + } - [Fact] - public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() + [Fact] + public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() + { + var mockOptions = new Mock>(); + var options = new CodeGeneratorOptions { - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); - - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Empty(options.OutputDir); - Assert.NotEmpty(outputProvider.OutputDir); - } + OutputDir = "" + }; + mockOptions.Setup(x => x.Value).Returns(options); - [Fact] - public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() + var outputProvider = new FileSystemOutputProvider(mockOptions.Object); + Assert.Empty(options.OutputDir); + Assert.NotEmpty(outputProvider.OutputDir); + } + + [Fact] + public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() + { + var expectedOutputDir = Environment.CurrentDirectory; + var mockOptions = new Mock>(); + var options = new CodeGeneratorOptions { - var expectedOutputDir = Environment.CurrentDirectory; - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); - - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); - } + OutputDir = "" + }; + mockOptions.Setup(x => x.Value).Returns(options); - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetClassCodeGenerator_Returns(bool structuredModel) + var outputProvider = new FileSystemOutputProvider(mockOptions.Object); + Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetClassCodeGenerator_Returns(bool structuredModel) + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { - var mockOptions = new Mock>(); - mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions - { - ManagementApi = false, - StructuredModel = structuredModel - }); + ManagementApi = false, + StructuredModel = structuredModel + }); - var deliveryClient = new Mock(); - var outputProvider = new Mock(); + var deliveryClient = new Mock(); + var outputProvider = new Mock(); - var elementCodename = "element_codename"; - var contentElement = new Mock(); - contentElement.SetupGet(element => element.Type).Returns("text"); - contentElement.SetupGet(element => element.Codename).Returns(elementCodename); + var elementCodename = "element_codename"; + var contentElement = new Mock(); + contentElement.SetupGet(element => element.Type).Returns("text"); + contentElement.SetupGet(element => element.Codename).Returns(elementCodename); - var contentType = new Mock(); - var contentTypeCodename = "Contenttype"; - contentType.SetupGet(type => type.System.Codename).Returns(contentTypeCodename); - contentType.SetupGet(type => type.Elements).Returns(new Dictionary { { elementCodename, contentElement.Object } }); + var contentType = new Mock(); + var contentTypeCodename = "Contenttype"; + contentType.SetupGet(type => type.System.Codename).Returns(contentTypeCodename); + contentType.SetupGet(type => type.Elements).Returns(new Dictionary { { elementCodename, contentElement.Object } }); - var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object); + var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object); - var result = codeGenerator.GetClassCodeGenerator(contentType.Object); + var result = codeGenerator.GetClassCodeGenerator(contentType.Object); - Assert.Equal($"{contentTypeCodename}.Generated", result.ClassFilename); - } + Assert.Equal($"{contentTypeCodename}.Generated", result.ClassFilename); + } - [Fact] - public async Task IntegrationTest_RunAsync_CorrectFiles() + [Fact] + public async Task IntegrationTest_RunAsync_CorrectFiles() + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When("https://deliver.kontent.ai/*") + .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); + var httpClient = mockHttp.ToHttpClient(); + + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When("https://deliver.kontent.ai/*") - .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); - var httpClient = mockHttp.ToHttpClient(); + DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = false, + GeneratePartials = false, + WithTypeProvider = false, + StructuredModel = false + }); - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, - Namespace = "CustomNamespace", - OutputDir = TempDir, - ManagementApi = false, - GeneratePartials = false, - WithTypeProvider = false, - StructuredModel = false - }); + var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); - var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); + var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); - var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); + await codeGenerator.RunAsync(); - await codeGenerator.RunAsync(); + Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs")); + Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs"))); + Assert.Empty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs")); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs")); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs"))); - Assert.Empty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs")); + // Cleanup + Directory.Delete(TempDir, true); + } - // Cleanup - Directory.Delete(TempDir, true); - } + [Fact] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When("https://deliver.kontent.ai/*") + .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); + var httpClient = mockHttp.ToHttpClient(); - [Fact] - public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() + const string transformFilename = "CustomSuffix"; + + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When("https://deliver.kontent.ai/*") - .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); - var httpClient = mockHttp.ToHttpClient(); + DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, + Namespace = "CustomNamespace", + OutputDir = TempDir, + GeneratePartials = false, + StructuredModel = false, + WithTypeProvider = false, + FileNameSuffix = transformFilename, + ManagementApi = false + }); - const string transformFilename = "CustomSuffix"; + var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, - Namespace = "CustomNamespace", - OutputDir = TempDir, - GeneratePartials = false, - StructuredModel = false, - WithTypeProvider = false, - FileNameSuffix = transformFilename, - ManagementApi = false - }); + var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); - var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); + await codeGenerator.RunAsync(); - var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); + Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); - await codeGenerator.RunAsync(); + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) + { + Assert.EndsWith($".{transformFilename}.cs", Path.GetFileName(filepath)); + } - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + // Cleanup + Directory.Delete(TempDir, true); + } - foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) - { - Assert.EndsWith($".{transformFilename}.cs", Path.GetFileName(filepath)); - } + [Fact] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When("https://deliver.kontent.ai/*") + .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); + var httpClient = mockHttp.ToHttpClient(); - // Cleanup - Directory.Delete(TempDir, true); - } + const string transformFilename = "Generated"; - [Fact] - public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When("https://deliver.kontent.ai/*") - .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); - var httpClient = mockHttp.ToHttpClient(); - - const string transformFilename = "Generated"; - - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, - Namespace = "CustomNamespace", - OutputDir = TempDir, - FileNameSuffix = transformFilename, - GeneratePartials = true, - WithTypeProvider = false, - StructuredModel = false, - ManagementApi = false - }); - - var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId) - .WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); - - var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); - - await codeGenerator.RunAsync(); - - var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; - var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; - Assert.Equal(allFilesCount, generatedCount * 2); - - foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs")) - { - var customFileExists = File.Exists(filepath.Replace($".{transformFilename}", "")); - Assert.True(customFileExists); - } - - // Cleanup - Directory.Delete(TempDir, true); - } + DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, + Namespace = "CustomNamespace", + OutputDir = TempDir, + FileNameSuffix = transformFilename, + GeneratePartials = true, + WithTypeProvider = false, + StructuredModel = false, + ManagementApi = false + }); + + var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId) + .WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); + + var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); - [Fact] - public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() + await codeGenerator.RunAsync(); + + var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; + var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; + Assert.Equal(allFilesCount, generatedCount * 2); + + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs")) { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.When("https://deliver.kontent.ai/*") - .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); - var httpClient = mockHttp.ToHttpClient(); + var customFileExists = File.Exists(filepath.Replace($".{transformFilename}", "")); + Assert.True(customFileExists); + } - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, - Namespace = "CustomNamespace", - OutputDir = TempDir, - ManagementApi = false, - GeneratePartials = false, - WithTypeProvider = true, - StructuredModel = false - }); + // Cleanup + Directory.Delete(TempDir, true); + } - var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); + [Fact] + public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() + { + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When("https://deliver.kontent.ai/*") + .Respond("application/json", await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "Fixtures/delivery_types.json"))); + var httpClient = mockHttp.ToHttpClient(); - var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + DeliveryOptions = new DeliveryOptions { ProjectId = ProjectId }, + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = false, + GeneratePartials = false, + WithTypeProvider = true, + StructuredModel = false + }); - await codeGenerator.RunAsync(); + var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); - Assert.Equal(NumberOfContentTypes + 1, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + var codeGenerator = new DeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), deliveryClient); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs")); + await codeGenerator.RunAsync(); - // Cleanup - Directory.Delete(TempDir, true); - } + Assert.Equal(NumberOfContentTypes + 1, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + + Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs")); + + // Cleanup + Directory.Delete(TempDir, true); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs b/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs index 54bcf6c4..54bb0070 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs @@ -6,34 +6,33 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Kontent.Ai.ModelGenerator.Tests.Fixtures +namespace Kontent.Ai.ModelGenerator.Tests.Fixtures; + +internal class ManagementModelsProvider { - internal class ManagementModelsProvider + public IEnumerator ManagementContentTypeModels { get; } + public IEnumerator ManagementContentTypeSnippetModels { get; } + + public ManagementModelsProvider() { - public IEnumerator ManagementContentTypeModels { get; } - public IEnumerator ManagementContentTypeSnippetModels { get; } + ManagementContentTypeModels = GetModels("Fixtures/management_types.json"); + ManagementContentTypeSnippetModels = GetModels("Fixtures/management_snippets.json"); + } - public ManagementModelsProvider() - { - ManagementContentTypeModels = GetModels("Fixtures/management_types.json"); - ManagementContentTypeSnippetModels = GetModels("Fixtures/management_snippets.json"); - } + private static IEnumerator GetModels(string filePath) + { + var stringServerResponse = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, filePath)); + var jTokenServerResponse = JToken.ReadFrom(new JsonTextReader(new StringReader(stringServerResponse))); - private static IEnumerator GetModels(string filePath) + var objectTypesProperty = Activator.CreateInstance(typeof(T)) switch { - var stringServerResponse = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, filePath)); - var jTokenServerResponse = JToken.ReadFrom(new JsonTextReader(new StringReader(stringServerResponse))); - - var objectTypesProperty = Activator.CreateInstance(typeof(T)) switch - { - ContentTypeModel => "types", - ContentTypeSnippetModel => "snippets", - _ => throw new NotSupportedException() - }; + ContentTypeModel => "types", + ContentTypeSnippetModel => "snippets", + _ => throw new NotSupportedException() + }; - return jTokenServerResponse[objectTypesProperty] - .ToObject>() - .GetEnumerator(); - } + return jTokenServerResponse[objectTypesProperty] + .ToObject>() + .GetEnumerator(); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs index 4ffece36..bd2e3bfb 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs @@ -3,53 +3,52 @@ using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class BaseClassCodeGeneratorTests { - public class BaseClassCodeGeneratorTests - { - private const string BaseClassName = "ContentBase"; + private const string BaseClassName = "ContentBase"; - [Fact] - public void GenerateBaseClassCodeWithDefaultNamespace() - { - var codeGenerator = new BaseClassCodeGenerator(BaseClassName); + [Fact] + public void GenerateBaseClassCodeWithDefaultNamespace() + { + var codeGenerator = new BaseClassCodeGenerator(BaseClassName); - var executingPath = AppContext.BaseDirectory; - var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); + var executingPath = AppContext.BaseDirectory; + var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); - var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); + var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); - Assert.Equal(expectedBaseClassCode, actualCompiledBaseClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); - } + Assert.Equal(expectedBaseClassCode, actualCompiledBaseClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); + } - [Fact] - public void GenerateBaseClassCodeWithCustomNamespace() - { - var customNamespace = "CustomNamespace"; - var codeGenerator = new BaseClassCodeGenerator(BaseClassName, customNamespace); + [Fact] + public void GenerateBaseClassCodeWithCustomNamespace() + { + var customNamespace = "CustomNamespace"; + var codeGenerator = new BaseClassCodeGenerator(BaseClassName, customNamespace); - var executingPath = AppContext.BaseDirectory; - var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); - expectedBaseClassCode = expectedBaseClassCode.Replace(ClassCodeGenerator.DefaultNamespace, customNamespace); + var executingPath = AppContext.BaseDirectory; + var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); + expectedBaseClassCode = expectedBaseClassCode.Replace(ClassCodeGenerator.DefaultNamespace, customNamespace); - var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); + var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); - Assert.Equal(expectedBaseClassCode, actualCompiledBaseClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); - } + Assert.Equal(expectedBaseClassCode, actualCompiledBaseClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); + } - [Fact] - public void GenerateExtenderClassCode() - { - var codeGenerator = new BaseClassCodeGenerator(BaseClassName); - codeGenerator.AddClassNameToExtend("Article"); - codeGenerator.AddClassNameToExtend("Office"); + [Fact] + public void GenerateExtenderClassCode() + { + var codeGenerator = new BaseClassCodeGenerator(BaseClassName); + codeGenerator.AddClassNameToExtend("Article"); + codeGenerator.AddClassNameToExtend("Office"); - var executingPath = AppContext.BaseDirectory; - var expectedExtenderCode = File.ReadAllText(executingPath + "/Assets/BaseClassExtender_CompiledCode.txt"); + var executingPath = AppContext.BaseDirectory; + var expectedExtenderCode = File.ReadAllText(executingPath + "/Assets/BaseClassExtender_CompiledCode.txt"); - var actualCompiledExtenderClass = codeGenerator.GenerateExtenderCode(); + var actualCompiledExtenderClass = codeGenerator.GenerateExtenderCode(); - Assert.Equal(expectedExtenderCode, actualCompiledExtenderClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); - } + Assert.Equal(expectedExtenderCode, actualCompiledExtenderClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTests.cs index c121bd89..a81436df 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTests.cs @@ -5,94 +5,93 @@ using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class ClassCodeGeneratorTests { - public class ClassCodeGeneratorTests + [Theory] + [MemberData(nameof(GetTypes))] + public void Constructor_ClassDefinitionIsNull_Throws(Type type) + { + var exception = Assert.Throws(() => Activator.CreateInstance(type, ConstructorParams())); + + Assert.NotNull(exception.InnerException); + Assert.Equal(typeof(ArgumentNullException), exception.InnerException.GetType()); + Assert.Contains("classDefinition", exception.InnerException.Message); + } + + [Theory] + [MemberData(nameof(GetTypesWithEmptyStringParam))] + public void Constructor_ClassFileNameIsNullOrEmptyOrWhiteSpace_Returns_ClassDefinitionCodename(Type type, string classFilename) + { + var classDefinitionCodename = "classdefinitioncodename"; + + var expectedClassFilename = "Classdefinitioncodename"; + + var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, classFilename)); + + Assert.NotNull(classCodeGenerator); + Assert.Equal(expectedClassFilename, classCodeGenerator.ClassFilename); + } + + [Theory] + [MemberData(nameof(GetTypes))] + public void Constructor_CustomClassFileName_Returns_CustomClassFileName(Type type) + { + var classDefinitionCodename = "codename"; + var classFilename = "CustomClassFileName"; + + var expectedClassFilename = "CustomClassFileName"; + + var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, classFilename)); + + Assert.NotNull(classCodeGenerator); + Assert.Equal(expectedClassFilename, classCodeGenerator.ClassFilename); + } + + [Theory] + [MemberData(nameof(GetTypesWithEmptyStringParam))] + public void Constructor_NamespaceIsNullOrEmptyOrWhiteSpace_Returns_DefaultNamespace(Type type, string @namespace) + { + var classDefinitionCodename = "classdefinitioncodename"; + + var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, null, @namespace)); + + Assert.NotNull(classCodeGenerator); + Assert.Equal(ClassCodeGenerator.DefaultNamespace, classCodeGenerator.Namespace); + } + + [Theory] + [MemberData(nameof(GetTypes))] + public void Constructor_CustomNamespace_Returns_CustomNamespace(Type type) + { + var classDefinitionCodename = "classdefinitioncodename"; + var customNamespace = "CustomNamespace"; + + var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, null, customNamespace)); + + Assert.NotNull(classCodeGenerator); + Assert.Equal(customNamespace, classCodeGenerator.Namespace); + } + + public static IEnumerable GetTypes() + { + yield return new object[] { typeof(PartialClassCodeGenerator) }; + yield return new object[] { typeof(ManagementClassCodeGenerator) }; + yield return new object[] { typeof(DeliveryClassCodeGenerator) }; + } + + public static IEnumerable GetTypesWithEmptyStringParam() { - [Theory] - [MemberData(nameof(GetTypes))] - public void Constructor_ClassDefinitionIsNull_Throws(Type type) - { - var exception = Assert.Throws(() => Activator.CreateInstance(type, ConstructorParams())); - - Assert.NotNull(exception.InnerException); - Assert.Equal(typeof(ArgumentNullException), exception.InnerException.GetType()); - Assert.Contains("classDefinition", exception.InnerException.Message); - } - - [Theory] - [MemberData(nameof(GetTypesWithEmptyStringParam))] - public void Constructor_ClassFileNameIsNullOrEmptyOrWhiteSpace_Returns_ClassDefinitionCodename(Type type, string classFilename) - { - var classDefinitionCodename = "classdefinitioncodename"; - - var expectedClassFilename = "Classdefinitioncodename"; - - var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, classFilename)); - - Assert.NotNull(classCodeGenerator); - Assert.Equal(expectedClassFilename, classCodeGenerator.ClassFilename); - } - - [Theory] - [MemberData(nameof(GetTypes))] - public void Constructor_CustomClassFileName_Returns_CustomClassFileName(Type type) - { - var classDefinitionCodename = "codename"; - var classFilename = "CustomClassFileName"; - - var expectedClassFilename = "CustomClassFileName"; - - var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, classFilename)); - - Assert.NotNull(classCodeGenerator); - Assert.Equal(expectedClassFilename, classCodeGenerator.ClassFilename); - } - - [Theory] - [MemberData(nameof(GetTypesWithEmptyStringParam))] - public void Constructor_NamespaceIsNullOrEmptyOrWhiteSpace_Returns_DefaultNamespace(Type type, string @namespace) - { - var classDefinitionCodename = "classdefinitioncodename"; - - var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, null, @namespace)); - - Assert.NotNull(classCodeGenerator); - Assert.Equal(ClassCodeGenerator.DefaultNamespace, classCodeGenerator.Namespace); - } - - [Theory] - [MemberData(nameof(GetTypes))] - public void Constructor_CustomNamespace_Returns_CustomNamespace(Type type) - { - var classDefinitionCodename = "classdefinitioncodename"; - var customNamespace = "CustomNamespace"; - - var classCodeGenerator = (ClassCodeGenerator)Activator.CreateInstance(type, ConstructorParams(classDefinitionCodename, null, customNamespace)); - - Assert.NotNull(classCodeGenerator); - Assert.Equal(customNamespace, classCodeGenerator.Namespace); - } - - public static IEnumerable GetTypes() - { - yield return new object[] { typeof(PartialClassCodeGenerator) }; - yield return new object[] { typeof(ManagementClassCodeGenerator) }; - yield return new object[] { typeof(DeliveryClassCodeGenerator) }; - } - - public static IEnumerable GetTypesWithEmptyStringParam() - { - yield return new object[] { typeof(PartialClassCodeGenerator), "" }; - yield return new object[] { typeof(ManagementClassCodeGenerator), " " }; - yield return new object[] { typeof(DeliveryClassCodeGenerator), null }; - } - - private static object[] ConstructorParams(string classDefinitionCodename = null, string classFileName = null, string @namespace = null) - => new object[] { GetClassDefinition(classDefinitionCodename), classFileName, @namespace }; - - private static ClassDefinition GetClassDefinition(string classDefinitionCodename) => classDefinitionCodename == null - ? (ClassDefinition)null - : new ClassDefinition(classDefinitionCodename); + yield return new object[] { typeof(PartialClassCodeGenerator), "" }; + yield return new object[] { typeof(ManagementClassCodeGenerator), " " }; + yield return new object[] { typeof(DeliveryClassCodeGenerator), null }; } + + private static object[] ConstructorParams(string classDefinitionCodename = null, string classFileName = null, string @namespace = null) + => new object[] { GetClassDefinition(classDefinitionCodename), classFileName, @namespace }; + + private static ClassDefinition GetClassDefinition(string classDefinitionCodename) => classDefinitionCodename == null + ? (ClassDefinition)null + : new ClassDefinition(classDefinitionCodename); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs index 9412e951..2637cbca 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs @@ -8,93 +8,92 @@ using Microsoft.CodeAnalysis.CSharp; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class DeliveryClassCodeGeneratorTests { - public class DeliveryClassCodeGeneratorTests + [Fact] + public void Constructor_CreatesInstance() { - [Fact] - public void Constructor_CreatesInstance() - { - var classDefinition = new ClassDefinition("Complete content type"); + var classDefinition = new ClassDefinition("Complete content type"); - var classCodeGenerator = new DeliveryClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new DeliveryClassCodeGenerator(classDefinition, classDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); - } + Assert.NotNull(classCodeGenerator); + Assert.True(classCodeGenerator.OverwriteExisting); + } - [Fact] - public void Build_CreatesClassWithCompleteContentType() - { - var classDefinition = new ClassDefinition("Complete content type"); - classDefinition.AddProperty(Property.FromContentTypeElement("text", "text")); - classDefinition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); - classDefinition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); - classDefinition.AddProperty(Property.FromContentTypeElement("number", "number")); - classDefinition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); - classDefinition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); - classDefinition.AddProperty(Property.FromContentTypeElement("asset", "asset")); - classDefinition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); - classDefinition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); - classDefinition.AddProperty(Property.FromContentTypeElement("url_slug", "url_slug")); - classDefinition.AddProperty(Property.FromContentTypeElement("custom", "custom")); + [Fact] + public void Build_CreatesClassWithCompleteContentType() + { + var classDefinition = new ClassDefinition("Complete content type"); + classDefinition.AddProperty(Property.FromContentTypeElement("text", "text")); + classDefinition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); + classDefinition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); + classDefinition.AddProperty(Property.FromContentTypeElement("number", "number")); + classDefinition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); + classDefinition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); + classDefinition.AddProperty(Property.FromContentTypeElement("asset", "asset")); + classDefinition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); + classDefinition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); + classDefinition.AddProperty(Property.FromContentTypeElement("url_slug", "url_slug")); + classDefinition.AddProperty(Property.FromContentTypeElement("custom", "custom")); - classDefinition.AddSystemProperty(); + classDefinition.AddSystemProperty(); - var classCodeGenerator = new DeliveryClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new DeliveryClassCodeGenerator(classDefinition, classDefinition.ClassName); - var compiledCode = classCodeGenerator.GenerateCode(); + var compiledCode = classCodeGenerator.GenerateCode(); - var executingPath = AppContext.BaseDirectory; - var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode.txt"); + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); - } + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + } - [Fact] - public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + [Fact] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + { + var definition = new ClassDefinition("Complete content type"); + definition.AddProperty(Property.FromContentTypeElement("text", "text")); + definition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); + definition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); + definition.AddProperty(Property.FromContentTypeElement("number", "number")); + definition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); + definition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); + definition.AddProperty(Property.FromContentTypeElement("asset", "asset")); + definition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); + definition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); + definition.AddProperty(Property.FromContentTypeElement("custom", "custom")); + + var classCodeGenerator = new DeliveryClassCodeGenerator(definition, definition.ClassName); + var compiledCode = classCodeGenerator.GenerateCode(); + + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, + references: new[] { + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + using var ms = new MemoryStream(); + var result = compilation.Emit(ms); + var compilationErrors = "Compilation errors:\n"; + + if (!result.Success) { - var definition = new ClassDefinition("Complete content type"); - definition.AddProperty(Property.FromContentTypeElement("text", "text")); - definition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); - definition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); - definition.AddProperty(Property.FromContentTypeElement("number", "number")); - definition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); - definition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); - definition.AddProperty(Property.FromContentTypeElement("asset", "asset")); - definition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); - definition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); - definition.AddProperty(Property.FromContentTypeElement("custom", "custom")); - - var classCodeGenerator = new DeliveryClassCodeGenerator(definition, definition.ClassName); - var compiledCode = classCodeGenerator.GenerateCode(); - - var compilation = CSharpCompilation.Create( - assemblyName: Path.GetRandomFileName(), - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, - references: new[] { - MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) - }, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - var compilationErrors = "Compilation errors:\n"; - - if (!result.Success) + var failures = result.Diagnostics.Where(diagnostic => + diagnostic.IsWarningAsError || + diagnostic.Severity == DiagnosticSeverity.Error); + + foreach (var diagnostic in failures) { - var failures = result.Diagnostics.Where(diagnostic => - diagnostic.IsWarningAsError || - diagnostic.Severity == DiagnosticSeverity.Error); - - foreach (var diagnostic in failures) - { - compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; - } + compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; } - - Assert.True(result.Success, compilationErrors); } + + Assert.True(result.Success, compilationErrors); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs index f20e6705..224fb2ee 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs @@ -9,119 +9,118 @@ using Microsoft.CodeAnalysis.CSharp; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class ManagementClassCodeGeneratorTests { - public class ManagementClassCodeGeneratorTests + [Fact] + public void Constructor_CreatesInstance() { - [Fact] - public void Constructor_CreatesInstance() - { - var classDefinition = new ClassDefinition("Complete content type"); + var classDefinition = new ClassDefinition("Complete content type"); - var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); - } + Assert.NotNull(classCodeGenerator); + Assert.True(classCodeGenerator.OverwriteExisting); + } - [Fact] - public void Build_CreatesClassWithCompleteContentType() - { - var classDefinition = new ClassDefinition("Complete content type"); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); - - var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); - - var compiledCode = classCodeGenerator.GenerateCode(); - - var executingPath = AppContext.BaseDirectory; - var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_ManagementApi.txt"); - - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); - } + [Fact] + public void Build_CreatesClassWithCompleteContentType() + { + var classDefinition = new ClassDefinition("Complete content type"); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); + + var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); + + var compiledCode = classCodeGenerator.GenerateCode(); + + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_ManagementApi.txt"); - [Fact] - public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + } + + [Fact] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + { + var classDefinition = new ClassDefinition("Complete content type"); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); + classDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); + + var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); + var compiledCode = classCodeGenerator.GenerateCode(); + + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, + references: new[] { + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location), + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(typeof(Management.Modules.ModelBuilders.IModelProvider).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(typeof(Management.Models.LanguageVariants.Elements.BaseElement).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.IJsonLineInfo).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + using var ms = new MemoryStream(); + var result = compilation.Emit(ms); + var compilationErrors = "Compilation errors:\n"; + + if (!result.Success) { - var classDefinition = new ClassDefinition("Complete content type"); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); - - var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); - var compiledCode = classCodeGenerator.GenerateCode(); - - var compilation = CSharpCompilation.Create( - assemblyName: Path.GetRandomFileName(), - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, - references: new[] { - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location), - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location), - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location), - MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(typeof(Management.Modules.ModelBuilders.IModelProvider).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(typeof(Management.Models.LanguageVariants.Elements.BaseElement).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.IJsonLineInfo).GetTypeInfo().Assembly.Location) - }, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - var compilationErrors = "Compilation errors:\n"; - - if (!result.Success) + var failures = result.Diagnostics.Where(diagnostic => + diagnostic.IsWarningAsError || + diagnostic.Severity == DiagnosticSeverity.Error); + + foreach (var diagnostic in failures) { - var failures = result.Diagnostics.Where(diagnostic => - diagnostic.IsWarningAsError || - diagnostic.Severity == DiagnosticSeverity.Error); - - foreach (var diagnostic in failures) - { - compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; - } + compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; } - - Assert.True(result.Success, compilationErrors); } + + Assert.True(result.Success, compilationErrors); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/PartialClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/PartialClassCodeGeneratorTests.cs index cff73aac..8afe21a2 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/PartialClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/PartialClassCodeGeneratorTests.cs @@ -4,34 +4,33 @@ using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class PartialClassCodeGeneratorTests { - public class PartialClassCodeGeneratorTests + [Fact] + public void Constructor_CreatesInstance() { - [Fact] - public void Constructor_CreatesInstance() - { - var classDefinition = new ClassDefinition("Complete content type"); + var classDefinition = new ClassDefinition("Complete content type"); - var classCodeGenerator = new PartialClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new PartialClassCodeGenerator(classDefinition, classDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.False(classCodeGenerator.OverwriteExisting); - } + Assert.NotNull(classCodeGenerator); + Assert.False(classCodeGenerator.OverwriteExisting); + } - [Fact] - public void Build_CreatesCustomPartialContentType() - { - var classDefinition = new ClassDefinition("Complete content type"); + [Fact] + public void Build_CreatesCustomPartialContentType() + { + var classDefinition = new ClassDefinition("Complete content type"); - var classCodeGenerator = new PartialClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new PartialClassCodeGenerator(classDefinition, classDefinition.ClassName); - var compiledCode = classCodeGenerator.GenerateCode(); + var compiledCode = classCodeGenerator.GenerateCode(); - var executingPath = AppContext.BaseDirectory; - var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_CustomPartial.txt"); + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_CustomPartial.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); - } + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/TypeProviderCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/TypeProviderCodeGeneratorTests.cs index 3f17b8e9..956851f1 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/TypeProviderCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/TypeProviderCodeGeneratorTests.cs @@ -8,70 +8,69 @@ using Xunit; using static System.String; -namespace Kontent.Ai.ModelGenerator.Tests.Generators +namespace Kontent.Ai.ModelGenerator.Tests.Generators; + +public class TypeProviderCodeGeneratorTests { - public class TypeProviderCodeGeneratorTests + [Fact] + public void GenerateCodeTests() { - [Fact] - public void GenerateCodeTests() - { - var codeGenerator = new TypeProviderCodeGenerator(); - codeGenerator.AddContentType("article", "Article"); - codeGenerator.AddContentType("office", "Office"); + var codeGenerator = new TypeProviderCodeGenerator(); + codeGenerator.AddContentType("article", "Article"); + codeGenerator.AddContentType("office", "Office"); - var executingPath = AppContext.BaseDirectory; - var expectedCode = File.ReadAllText(executingPath + "/Assets/CustomTypeProvider_CompiledCode.txt"); + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/CustomTypeProvider_CompiledCode.txt"); - var compiledCode = codeGenerator.GenerateCode(); + var compiledCode = codeGenerator.GenerateCode(); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); - } + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + } - [Fact] - public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() - { - var codeGenerator = new TypeProviderCodeGenerator(); - codeGenerator.AddContentType("article", "Article"); - codeGenerator.AddContentType("office", "Office"); + [Fact] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + { + var codeGenerator = new TypeProviderCodeGenerator(); + codeGenerator.AddContentType("article", "Article"); + codeGenerator.AddContentType("office", "Office"); - var compiledCode = codeGenerator.GenerateCode(); + var compiledCode = codeGenerator.GenerateCode(); - // Dummy implementation of Article and Office class to make compilation work - var dummyClasses = "public class Article {} public class Office {}"; + // Dummy implementation of Article and Office class to make compilation work + var dummyClasses = "public class Article {} public class Office {}"; - var compilation = CSharpCompilation.Create( - assemblyName: Path.GetRandomFileName(), - syntaxTrees: new[] { - CSharpSyntaxTree.ParseText(compiledCode), - CSharpSyntaxTree.ParseText(dummyClasses) - }, - references: new[] { - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location), - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location), - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location), - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq")).Location), - MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) - }, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] { + CSharpSyntaxTree.ParseText(compiledCode), + CSharpSyntaxTree.ParseText(dummyClasses) + }, + references: new[] { + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq")).Location), + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - var compilationErrors = $"Compilation errors:{Environment.NewLine}"; + using var ms = new MemoryStream(); + var result = compilation.Emit(ms); + var compilationErrors = $"Compilation errors:{Environment.NewLine}"; - if (!result.Success) - { - var failures = result.Diagnostics.Where(diagnostic => - diagnostic.IsWarningAsError || - diagnostic.Severity == DiagnosticSeverity.Error); + if (!result.Success) + { + var failures = result.Diagnostics.Where(diagnostic => + diagnostic.IsWarningAsError || + diagnostic.Severity == DiagnosticSeverity.Error); - foreach (var diagnostic in failures) - { - compilationErrors += Format($"{diagnostic.Id}: {diagnostic.GetMessage()}{Environment.NewLine}"); - } + foreach (var diagnostic in failures) + { + compilationErrors += Format($"{diagnostic.Id}: {diagnostic.GetMessage()}{Environment.NewLine}"); } - - Assert.True(result.Success, compilationErrors); } + + Assert.True(result.Success, compilationErrors); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs index 3e57b14a..143295c5 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs @@ -3,52 +3,51 @@ using Kontent.Ai.ModelGenerator.Core.Helpers; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Helpers +namespace Kontent.Ai.ModelGenerator.Tests.Helpers; + +public class DeliveryElementHelperTests { - public class DeliveryElementHelperTests + [Fact] + public void GetElementType_OptionsIsNull_ThrowsException() { - [Fact] - public void GetElementType_OptionsIsNull_ThrowsException() - { - Assert.Throws(() => DeliveryElementHelper.GetElementType(null, "type")); - } + Assert.Throws(() => DeliveryElementHelper.GetElementType(null, "type")); + } - [Fact] - public void GetElementType_ElementTypeIsNull_ThrowsException() - { - Assert.Throws(() => DeliveryElementHelper.GetElementType(new CodeGeneratorOptions { ManagementApi = false }, null)); - } + [Fact] + public void GetElementType_ElementTypeIsNull_ThrowsException() + { + Assert.Throws(() => DeliveryElementHelper.GetElementType(new CodeGeneratorOptions { ManagementApi = false }, null)); + } - [Fact] - public void GetElementType_ManagementApiIsTrue_ThrowsException() - { - Assert.Throws(() => DeliveryElementHelper.GetElementType(new CodeGeneratorOptions { ManagementApi = true }, "type")); - } + [Fact] + public void GetElementType_ManagementApiIsTrue_ThrowsException() + { + Assert.Throws(() => DeliveryElementHelper.GetElementType(new CodeGeneratorOptions { ManagementApi = true }, "type")); + } - [Fact] - public void GetElementType_StructuredModel_ReturnsStructuredElementType() + [Fact] + public void GetElementType_StructuredModel_ReturnsStructuredElementType() + { + var result = DeliveryElementHelper.GetElementType(new CodeGeneratorOptions { - var result = DeliveryElementHelper.GetElementType(new CodeGeneratorOptions - { - ManagementApi = false, - StructuredModel = true - }, "rich_text"); - - Assert.Equal("rich_text(structured)", result); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetElementType_Returns(bool structuredModel) + ManagementApi = false, + StructuredModel = true + }, "rich_text"); + + Assert.Equal("rich_text(structured)", result); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetElementType_Returns(bool structuredModel) + { + var result = DeliveryElementHelper.GetElementType(new CodeGeneratorOptions { - var result = DeliveryElementHelper.GetElementType(new CodeGeneratorOptions - { - ManagementApi = false, - StructuredModel = structuredModel - }, "text"); - - Assert.Equal("text", result); - } + ManagementApi = false, + StructuredModel = structuredModel + }, "text"); + + Assert.Equal("text", result); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs index c113c619..fa744d60 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs @@ -6,120 +6,119 @@ using Kontent.Ai.ModelGenerator.Core.Helpers; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Helpers +namespace Kontent.Ai.ModelGenerator.Tests.Helpers; + +public class ManagementElementHelperTests { - public class ManagementElementHelperTests + [Fact] + public void GetManagementContentTypeSnippetElements_ManagementSnippetsAreNull_ThrowsException() { - [Fact] - public void GetManagementContentTypeSnippetElements_ManagementSnippetsAreNull_ThrowsException() - { - Assert.Throws(() => - ManagementElementHelper.GetManagementContentTypeSnippetElements(new TextElementMetadataModel(), null)); - } + Assert.Throws(() => + ManagementElementHelper.GetManagementContentTypeSnippetElements(new TextElementMetadataModel(), null)); + } - [Fact] - public void GetManagementContentTypeSnippetElements_ManagementContentTypeIsNull_ThrowsException() - { - Assert.Throws(() => - ManagementElementHelper.GetManagementContentTypeSnippetElements(null, new List())); - } + [Fact] + public void GetManagementContentTypeSnippetElements_ManagementContentTypeIsNull_ThrowsException() + { + Assert.Throws(() => + ManagementElementHelper.GetManagementContentTypeSnippetElements(null, new List())); + } - [Fact] - public void GetManagementContentTypeSnippetElements_NoSnippetElements_Throws() - { - var contentTypeElementCodename = "codename"; + [Fact] + public void GetManagementContentTypeSnippetElements_NoSnippetElements_Throws() + { + var contentTypeElementCodename = "codename"; - var snippets = new List + var snippets = new List + { + new ContentTypeSnippetModel { - new ContentTypeSnippetModel - { - Codename = contentTypeElementCodename, - Elements = new List() - } - }; + Codename = contentTypeElementCodename, + Elements = new List() + } + }; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); - var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets); + var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets); - Assert.NotNull(result); - Assert.Empty(result); - } + Assert.NotNull(result); + Assert.Empty(result); + } - [Fact] - public void GetManagementContentTypeSnippetElements_NoSnippets_Throws() - { - var contentTypeElementCodename = "codename"; + [Fact] + public void GetManagementContentTypeSnippetElements_NoSnippets_Throws() + { + var contentTypeElementCodename = "codename"; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); - Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, new List())); - } + Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, new List())); + } - [Fact] - public void GetManagementContentTypeSnippetElements_NoMatchingSnippet_Throws() - { - var contentTypeElementCodename = "codename"; - var snippetCodename = "other_snippet_codename"; + [Fact] + public void GetManagementContentTypeSnippetElements_NoMatchingSnippet_Throws() + { + var contentTypeElementCodename = "codename"; + var snippetCodename = "other_snippet_codename"; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); - var snippets = new List + var snippets = new List + { + new ContentTypeSnippetModel { - new ContentTypeSnippetModel + Codename = snippetCodename, + Elements = new List { - Codename = snippetCodename, - Elements = new List - { - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el"), - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el2", ElementMetadataType.Number) - } + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el"), + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el2", ElementMetadataType.Number) } - }; + } + }; - Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets)); - } + Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets)); + } - [Fact] - public void GetManagementContentTypeSnippetElements_NotManagementContentTypeSnippetElement_ReturnsNull() - { - var snippetCodename = "codename"; + [Fact] + public void GetManagementContentTypeSnippetElements_NotManagementContentTypeSnippetElement_ReturnsNull() + { + var snippetCodename = "codename"; - var element = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename); + var element = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename); - var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, new List()); + var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, new List()); - Assert.Null(result); - } + Assert.Null(result); + } - [Fact] - public void GetManagementContentTypeSnippetElements_Returns() - { - var expectedElementId = Guid.NewGuid(); - var expectedElement2Id = Guid.NewGuid(); - var snippetCodename = "snippet_codename"; + [Fact] + public void GetManagementContentTypeSnippetElements_Returns() + { + var expectedElementId = Guid.NewGuid(); + var expectedElement2Id = Guid.NewGuid(); + var snippetCodename = "snippet_codename"; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename, ElementMetadataType.ContentTypeSnippet); - var snippets = new List + var snippets = new List + { + new ContentTypeSnippetModel { - new ContentTypeSnippetModel + Codename = snippetCodename, + Elements = new List { - Codename = snippetCodename, - Elements = new List - { - TestHelper.GenerateElementMetadataBase(expectedElementId, $"{snippetCodename}_el"), - TestHelper.GenerateElementMetadataBase(expectedElement2Id, $"{snippetCodename}_el2", ElementMetadataType.Number) - } + TestHelper.GenerateElementMetadataBase(expectedElementId, $"{snippetCodename}_el"), + TestHelper.GenerateElementMetadataBase(expectedElement2Id, $"{snippetCodename}_el2", ElementMetadataType.Number) } - }; + } + }; - var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets).ToList(); + var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets).ToList(); - Assert.NotNull(result); - Assert.Equal(2, result.Count); - Assert.Contains(result, el => el.Id == expectedElementId); - Assert.Contains(result, el => el.Id == expectedElement2Id); - } + Assert.NotNull(result); + Assert.Equal(2, result.Count); + Assert.Contains(result, el => el.Id == expectedElementId); + Assert.Contains(result, el => el.Id == expectedElement2Id); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs index 5dc9c113..5083cc1e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs @@ -3,66 +3,65 @@ using Kontent.Ai.ModelGenerator.Core.Helpers; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests.Helpers +namespace Kontent.Ai.ModelGenerator.Tests.Helpers; + +public class TextHelpersTests { - public class TextHelpersTests + [Fact] + public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForNullValue() { - [Fact] - public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForNullValue() - { - Assert.Throws(() => TextHelpers.GetValidPascalCaseIdentifierName(null)); - } + Assert.Throws(() => TextHelpers.GetValidPascalCaseIdentifierName(null)); + } - [Theory] - [InlineData("")] - [InlineData(" ")] - [InlineData("-")] - [InlineData("$^123")] - public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForInvalidInput(string name) - { - Assert.Throws(() => TextHelpers.GetValidPascalCaseIdentifierName(name)); - } + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData("-")] + [InlineData("$^123")] + public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForInvalidInput(string name) + { + Assert.Throws(() => TextHelpers.GetValidPascalCaseIdentifierName(name)); + } - [Theory] - [InlineData("Simple name", "SimpleName")] - [InlineData("Name with special chars & multiple spaces.", "NameWithSpecialCharsMultipleSpaces")] - [InlineData("EVERYTHING_IS_ -UPPERCASE", "EverythingIsUppercase")] - [InlineData("date___time_field", "DateTimeField")] - [InlineData("Multiline\r\nstring", "MultilineString")] - [InlineData(" 1 2 3 Starts with space and numbers", "StartsWithSpaceAndNumbers")] - [InlineData("ends with numbers 1 2 3", "EndsWithNumbers123")] - public void GetValidPascalCaseIdentifierName(string name, string expected) - { - string result = TextHelpers.GetValidPascalCaseIdentifierName(name); - Assert.Equal(expected, result); - } + [Theory] + [InlineData("Simple name", "SimpleName")] + [InlineData("Name with special chars & multiple spaces.", "NameWithSpecialCharsMultipleSpaces")] + [InlineData("EVERYTHING_IS_ -UPPERCASE", "EverythingIsUppercase")] + [InlineData("date___time_field", "DateTimeField")] + [InlineData("Multiline\r\nstring", "MultilineString")] + [InlineData(" 1 2 3 Starts with space and numbers", "StartsWithSpaceAndNumbers")] + [InlineData("ends with numbers 1 2 3", "EndsWithNumbers123")] + public void GetValidPascalCaseIdentifierName(string name, string expected) + { + string result = TextHelpers.GetValidPascalCaseIdentifierName(name); + Assert.Equal(expected, result); + } - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public void GenerateCommentString_CustomCommentIsNullOrEmptyOrWhiteSpace_Throws(string customComment) - { - Assert.Throws(() => TextHelpers.GenerateCommentString(customComment)); - } + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void GenerateCommentString_CustomCommentIsNullOrEmptyOrWhiteSpace_Throws(string customComment) + { + Assert.Throws(() => TextHelpers.GenerateCommentString(customComment)); + } - [Fact] - public void GenerateCommentString_Returns() - { - var customComment = "// custom comment"; + [Fact] + public void GenerateCommentString_Returns() + { + var customComment = "// custom comment"; - var expectedComment = -@$"// + var expectedComment = + @$"// // This code was generated by a kontent-generators-net tool // (see https://github.com/kontent-ai/model-generator-net). // // custom comment // {Environment.NewLine}{Environment.NewLine}"; - var result = TextHelpers.GenerateCommentString(customComment); + var result = TextHelpers.GenerateCommentString(customComment); - Assert.Equal(expectedComment, result); + Assert.Equal(expectedComment, result); - } } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs index e86de39d..5db85460 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs @@ -16,208 +16,207 @@ using Moq; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests +namespace Kontent.Ai.ModelGenerator.Tests; + +public class ManagementCodeGeneratorTests : CodeGeneratorTestsBase { - public class ManagementCodeGeneratorTests : CodeGeneratorTestsBase + /// + /// represents count of elements in 'management_types.json' + /// + private const int NumberOfContentTypes = 14; + private readonly IManagementClient _managementClient; + protected override string TempDir => Path.Combine(Path.GetTempPath(), "ManagementCodeGeneratorIntegrationTests"); + + public ManagementCodeGeneratorTests() { - /// - /// represents count of elements in 'management_types.json' - /// - private const int NumberOfContentTypes = 14; - private readonly IManagementClient _managementClient; - protected override string TempDir => Path.Combine(Path.GetTempPath(), "ManagementCodeGeneratorIntegrationTests"); - - public ManagementCodeGeneratorTests() - { - _managementClient = CreateManagementClient(); - } + _managementClient = CreateManagementClient(); + } - [Fact] - public void Constructor_ManagementIsTrue_Throws() + [Fact] + public void Constructor_ManagementIsTrue_Throws() + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { - var mockOptions = new Mock>(); - mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions - { - ManagementApi = false - }); + ManagementApi = false + }); - var outputProvider = new Mock(); + var outputProvider = new Mock(); - Assert.Throws(() => new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, _managementClient)); - } + Assert.Throws(() => new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, _managementClient)); + } - [Fact] - public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() + [Fact] + public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() + { + var mockOptions = new Mock>(); + var options = new CodeGeneratorOptions { - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); + OutputDir = "" + }; + mockOptions.Setup(x => x.Value).Returns(options); - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Empty(options.OutputDir); - Assert.NotEmpty(outputProvider.OutputDir); - } + var outputProvider = new FileSystemOutputProvider(mockOptions.Object); + Assert.Empty(options.OutputDir); + Assert.NotEmpty(outputProvider.OutputDir); + } - [Fact] - public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() + [Fact] + public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() + { + var expectedOutputDir = Environment.CurrentDirectory; + var mockOptions = new Mock>(); + var options = new CodeGeneratorOptions { - var expectedOutputDir = Environment.CurrentDirectory; - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); + OutputDir = "" + }; + mockOptions.Setup(x => x.Value).Returns(options); - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); - } + var outputProvider = new FileSystemOutputProvider(mockOptions.Object); + Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); + } - [Fact] - public void GetClassCodeGenerator_Returns() + [Fact] + public void GetClassCodeGenerator_Returns() + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { - var mockOptions = new Mock>(); - mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions - { - ManagementApi = true - }); + ManagementApi = true + }); - var outputProvider = new Mock(); - var managementClient = new Mock(); + var outputProvider = new Mock(); + var managementClient = new Mock(); - var contentTypeCodename = "Contenttype"; - var elementCodename = "element_codename"; - var contentType = new ContentTypeModel + var contentTypeCodename = "Contenttype"; + var elementCodename = "element_codename"; + var contentType = new ContentTypeModel + { + Codename = contentTypeCodename, + Elements = new List { - Codename = contentTypeCodename, - Elements = new List - { - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), elementCodename) - } - }; + TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), elementCodename) + } + }; - var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, managementClient.Object); + var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, managementClient.Object); - var result = codeGenerator.GetClassCodeGenerator(contentType, new List()); + var result = codeGenerator.GetClassCodeGenerator(contentType, new List()); - Assert.Equal($"{contentTypeCodename}.Generated", result.ClassFilename); - } + Assert.Equal($"{contentTypeCodename}.Generated", result.ClassFilename); + } - [Fact] - public async Task IntegrationTest_RunAsync_CorrectFiles() + [Fact] + public async Task IntegrationTest_RunAsync_CorrectFiles() + { + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - Namespace = "CustomNamespace", - OutputDir = TempDir, - ManagementApi = true, - GeneratePartials = false, - ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId } - }); + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = true, + GeneratePartials = false, + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId } + }); - var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); - await codeGenerator.RunAsync(); + await codeGenerator.RunAsync(); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs")); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs"))); + Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs")); + Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs"))); - // Cleanup - Directory.Delete(TempDir, true); - } - - [Fact] - public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() - { - const string transformFilename = "CustomSuffix"; + // Cleanup + Directory.Delete(TempDir, true); + } - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, - Namespace = "CustomNamespace", - OutputDir = TempDir, - GeneratePartials = false, - FileNameSuffix = transformFilename, - ManagementApi = true - }); + [Fact] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() + { + const string transformFilename = "CustomSuffix"; - var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, + Namespace = "CustomNamespace", + OutputDir = TempDir, + GeneratePartials = false, + FileNameSuffix = transformFilename, + ManagementApi = true + }); - await codeGenerator.RunAsync(); + var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + await codeGenerator.RunAsync(); - foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) - { - Assert.EndsWith($".{transformFilename}.cs", Path.GetFileName(filepath)); - } + Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); - // Cleanup - Directory.Delete(TempDir, true); + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) + { + Assert.EndsWith($".{transformFilename}.cs", Path.GetFileName(filepath)); } - [Fact] - public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() - { - const string transformFilename = "Generated"; + // Cleanup + Directory.Delete(TempDir, true); + } - var mockOptions = new Mock>(); - mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions - { - Namespace = "CustomNamespace", - OutputDir = TempDir, - FileNameSuffix = transformFilename, - GeneratePartials = true, - ManagementApi = true, - ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId } - }); + [Fact] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() + { + const string transformFilename = "Generated"; - var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + Namespace = "CustomNamespace", + OutputDir = TempDir, + FileNameSuffix = transformFilename, + GeneratePartials = true, + ManagementApi = true, + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId } + }); - await codeGenerator.RunAsync(); + var codeGenerator = new ManagementCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); - var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; - var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; - Assert.Equal(allFilesCount, generatedCount * 2); + await codeGenerator.RunAsync(); - foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs")) - { - var customFileExists = File.Exists(filepath.Replace($".{transformFilename}", "")); - Assert.True(customFileExists); - } + var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; + var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; + Assert.Equal(allFilesCount, generatedCount * 2); - // Cleanup - Directory.Delete(TempDir, true); + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs")) + { + var customFileExists = File.Exists(filepath.Replace($".{transformFilename}", "")); + Assert.True(customFileExists); } - private static IManagementClient CreateManagementClient() - { - var managementModelsProvider = new ManagementModelsProvider(); - var managementClientMock = new Mock(); + // Cleanup + Directory.Delete(TempDir, true); + } - var contentTypeListingResponseModel = new Mock>(); - contentTypeListingResponseModel.As>() - .Setup(c => c.GetEnumerator()) - .Returns(() => managementModelsProvider.ManagementContentTypeModels); + private static IManagementClient CreateManagementClient() + { + var managementModelsProvider = new ManagementModelsProvider(); + var managementClientMock = new Mock(); - var contentTypeSnippetListingResponseModel = new Mock>(); - contentTypeSnippetListingResponseModel.As>() - .Setup(c => c.GetEnumerator()) - .Returns(() => managementModelsProvider.ManagementContentTypeSnippetModels); + var contentTypeListingResponseModel = new Mock>(); + contentTypeListingResponseModel.As>() + .Setup(c => c.GetEnumerator()) + .Returns(() => managementModelsProvider.ManagementContentTypeModels); - managementClientMock.Setup(client => client.ListContentTypeSnippetsAsync()) - .Returns(Task.FromResult(contentTypeSnippetListingResponseModel.Object)); - managementClientMock.Setup(client => client.ListContentTypesAsync()) - .Returns(Task.FromResult(contentTypeListingResponseModel.Object)); + var contentTypeSnippetListingResponseModel = new Mock>(); + contentTypeSnippetListingResponseModel.As>() + .Setup(c => c.GetEnumerator()) + .Returns(() => managementModelsProvider.ManagementContentTypeSnippetModels); - return managementClientMock.Object; - } + managementClientMock.Setup(client => client.ListContentTypeSnippetsAsync()) + .Returns(Task.FromResult(contentTypeSnippetListingResponseModel.Object)); + managementClientMock.Setup(client => client.ListContentTypesAsync()) + .Returns(Task.FromResult(contentTypeListingResponseModel.Object)); + + return managementClientMock.Object; } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ProgramTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ProgramTests.cs index da0b4737..5a1f513b 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ProgramTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ProgramTests.cs @@ -2,15 +2,14 @@ using System.Threading.Tasks; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests +namespace Kontent.Ai.ModelGenerator.Tests; + +public class ProgramTests { - public class ProgramTests + [Fact] + public async Task CreateCodeGeneratorOptions_NoProjectId_ReturnsError() { - [Fact] - public async Task CreateCodeGeneratorOptions_NoProjectId_ReturnsError() - { - var result = await Program.Main(Array.Empty()); - Assert.Equal(1, result); - } + var result = await Program.Main(Array.Empty()); + Assert.Equal(1, result); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs index b477050f..d09b39b9 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs @@ -2,26 +2,25 @@ using Kontent.Ai.Management.Models.Types.Elements; using Newtonsoft.Json.Linq; -namespace Kontent.Ai.ModelGenerator.Tests +namespace Kontent.Ai.ModelGenerator.Tests; + +internal static class TestHelper { - internal static class TestHelper - { - public static ElementMetadataBase GenerateElementMetadataBase(Guid elementId, string elementCodename, ElementMetadataType type = ElementMetadataType.Text) => - JObject.FromObject(new - { - Id = elementId, - Codename = elementCodename, - type - }).ToObject(); + public static ElementMetadataBase GenerateElementMetadataBase(Guid elementId, string elementCodename, ElementMetadataType type = ElementMetadataType.Text) => + JObject.FromObject(new + { + Id = elementId, + Codename = elementCodename, + type + }).ToObject(); - public static ElementMetadataBase GenerateGuidelinesElement(Guid elementId, string elementCodename) => - JObject.FromObject(new - { - Id = elementId, - Codename = elementCodename, - type = ElementMetadataType.Guidelines, - guidelines = "guidelines" + public static ElementMetadataBase GenerateGuidelinesElement(Guid elementId, string elementCodename) => + JObject.FromObject(new + { + Id = elementId, + Codename = elementCodename, + type = ElementMetadataType.Guidelines, + guidelines = "guidelines" - }).ToObject(); - } + }).ToObject(); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs index 1293a739..f9e860a4 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs @@ -4,132 +4,131 @@ using Kontent.Ai.ModelGenerator.Core.Configuration; using Xunit; -namespace Kontent.Ai.ModelGenerator.Tests +namespace Kontent.Ai.ModelGenerator.Tests; + +public class ValidationExtensionsTests { - public class ValidationExtensionsTests + [Fact] + public void Validate_ManagementOptions_Success() { - [Fact] - public void Validate_ManagementOptions_Success() + var projectId = Guid.NewGuid().ToString(); + var codeGeneratorOptions = new CodeGeneratorOptions { - var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + ManagementApi = true, + ManagementOptions = new ManagementOptions { - ManagementApi = true, - ManagementOptions = new ManagementOptions - { - ProjectId = projectId, - ApiKey = "apiKey" - } - }; + ProjectId = projectId, + ApiKey = "apiKey" + } + }; - codeGeneratorOptions.Validate(); - } + codeGeneratorOptions.Validate(); + } - [Fact] - public void Validate_DeliveryOptions_Success() + [Fact] + public void Validate_DeliveryOptions_Success() + { + var projectId = Guid.NewGuid().ToString(); + var codeGeneratorOptions = new CodeGeneratorOptions { - var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + ManagementApi = false, + DeliveryOptions = new DeliveryOptions { - ManagementApi = false, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - } - }; + ProjectId = projectId + } + }; - codeGeneratorOptions.Validate(); - } + codeGeneratorOptions.Validate(); + } - [Fact] - public void Validate_DeliveryOptionsIsNull_ThrowsException() + [Fact] + public void Validate_DeliveryOptionsIsNull_ThrowsException() + { + var codeGeneratorOptions = new CodeGeneratorOptions { - var codeGeneratorOptions = new CodeGeneratorOptions - { - DeliveryOptions = null - }; + DeliveryOptions = null + }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide at least the 'ProjectId' argument. See http://bit.ly/k-params for more details on configuration.", exception.Message); - } + var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); + Assert.Equal("You have to provide at least the 'ProjectId' argument. See http://bit.ly/k-params for more details on configuration.", exception.Message); + } - [Fact] - public void Validate_DeliveryOptionsProjectIdIsNull_ThrowsException() + [Fact] + public void Validate_DeliveryOptionsProjectIdIsNull_ThrowsException() + { + var codeGeneratorOptions = new CodeGeneratorOptions { - var codeGeneratorOptions = new CodeGeneratorOptions + DeliveryOptions = new DeliveryOptions { - DeliveryOptions = new DeliveryOptions - { - ProjectId = null - } - }; + ProjectId = null + } + }; - Assert.Throws(() => codeGeneratorOptions.Validate()); - } + Assert.Throws(() => codeGeneratorOptions.Validate()); + } - [Fact] - public void Validate_ManagementOptionsIsNull_ThrowsException() + [Fact] + public void Validate_ManagementOptionsIsNull_ThrowsException() + { + var projectId = Guid.NewGuid().ToString(); + var codeGeneratorOptions = new CodeGeneratorOptions { - var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + ManagementApi = true, + DeliveryOptions = new DeliveryOptions { - ManagementApi = true, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - }, - ManagementOptions = null - }; + ProjectId = projectId + }, + ManagementOptions = null + }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide the 'ProjectId' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); - } + var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); + Assert.Equal("You have to provide the 'ProjectId' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); + } - [Fact] - public void Validate_ManagementOptionsProjectIdIsNull_ThrowsException() + [Fact] + public void Validate_ManagementOptionsProjectIdIsNull_ThrowsException() + { + var projectId = Guid.NewGuid().ToString(); + var codeGeneratorOptions = new CodeGeneratorOptions { - var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + ManagementApi = true, + DeliveryOptions = new DeliveryOptions { - ManagementApi = true, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - }, - ManagementOptions = new ManagementOptions - { - ProjectId = null, - ApiKey = "apiKey" - } - }; + ProjectId = projectId + }, + ManagementOptions = new ManagementOptions + { + ProjectId = null, + ApiKey = "apiKey" + } + }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide the 'ProjectId' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); - } + var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); + Assert.Equal("You have to provide the 'ProjectId' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); + } - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException(string apiKey) + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException(string apiKey) + { + var projectId = Guid.NewGuid().ToString(); + var codeGeneratorOptions = new CodeGeneratorOptions { - var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + ManagementApi = true, + DeliveryOptions = new DeliveryOptions + { + ProjectId = projectId + }, + ManagementOptions = new ManagementOptions { - ManagementApi = true, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - }, - ManagementOptions = new ManagementOptions - { - ProjectId = projectId, - ApiKey = apiKey - } - }; + ProjectId = projectId, + ApiKey = apiKey + } + }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide the 'ApiKey' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); - } + var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); + Assert.Equal("You have to provide the 'ApiKey' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); } } From 946f489ecdd92a0ff9f82920c674cf2eeeb468d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 8 Sep 2022 15:01:54 +0200 Subject: [PATCH 02/48] 90 introduce option for ExtendedDeliverModels --- .../Configuration/CodeGeneratorOptions.cs | 12 ++++ .../CodeGeneratorOptionsExtensions.cs | 7 +++ src/Kontent.Ai.ModelGenerator/Program.cs | 11 ++-- .../CodeGeneratorOptionsExtensionsTests.cs | 59 +++++++++++++++++++ 4 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs index 2a439d1b..92cc5e53 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs @@ -5,6 +5,8 @@ namespace Kontent.Ai.ModelGenerator.Core.Configuration; public class CodeGeneratorOptions { + private const bool DefaultExtendedDeliverModels = false; + private const bool DefaultExtendedDeliverPreviewModels = false; private const bool DefaultGeneratePartials = true; private const bool DefaultWithTypeProvider = true; private const bool DefaultStructuredModel = false; @@ -21,6 +23,16 @@ public class CodeGeneratorOptions /// public ManagementOptions ManagementOptions { get; set; } + /// + /// Indicates whether the extended Delivery models should be generated + /// + public bool ExtendedDeliverModels { get; set; } = DefaultExtendedDeliverModels; + + /// + /// Indicates whether the extended preview Delivery models should be generated + /// + public bool ExtendedDeliverPreviewModels { get; set; } = DefaultExtendedDeliverPreviewModels; + /// /// Namespace name of the generated classes /// diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs new file mode 100644 index 00000000..e394af9b --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -0,0 +1,7 @@ +namespace Kontent.Ai.ModelGenerator.Core.Configuration; + +public static class CodeGeneratorOptionsExtensions +{ + public static bool ManagementApi(this CodeGeneratorOptions options) => + options.ManagementApi && !options.ExtendedDeliverModels && !options.ExtendedDeliverPreviewModels; +} diff --git a/src/Kontent.Ai.ModelGenerator/Program.cs b/src/Kontent.Ai.ModelGenerator/Program.cs index c9bea69a..4437e7d8 100644 --- a/src/Kontent.Ai.ModelGenerator/Program.cs +++ b/src/Kontent.Ai.ModelGenerator/Program.cs @@ -52,9 +52,12 @@ public static async Task Main(string[] args) PrintSdkVersion(options); // Code generator entry point - return options.ManagementApi - ? await serviceProvider.GetService().RunAsync() - : await serviceProvider.GetService().RunAsync(); + if (options.ManagementApi()) + { + return await serviceProvider.GetService().RunAsync(); + } + + return await serviceProvider.GetService().RunAsync(); } catch (AggregateException aex) { @@ -76,7 +79,7 @@ public static async Task Main(string[] args) private static void PrintSdkVersion(CodeGeneratorOptions options) { - var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(options.ManagementApi); + var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(options.ManagementApi()); Console.WriteLine($"Models were generated for {usedSdkInfo.Name} version {usedSdkInfo.Version}"); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs new file mode 100644 index 00000000..6c3674c4 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -0,0 +1,59 @@ +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Xunit; + +namespace Kontent.Ai.ModelGenerator.Tests.Configuration; + +public class CodeGeneratorOptionsExtensionsTests +{ + [Fact] + public void ManagementApi_ManagementApi_ReturnsTrue() + { + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }; + + var result = options.ManagementApi(); + + Assert.True(result); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = options.ManagementApi(); + + Assert.False(result); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = options.ManagementApi(); + + Assert.False(result); + } +} From 31d3c9ef8554463e7df752fe42186a03f535a14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Sat, 10 Sep 2022 21:40:25 +0200 Subject: [PATCH 03/48] 90 argument and options handling --- src/Kontent.Ai.ModelGenerator/ArgHelpers.cs | 98 ----------- .../Kontent.Ai.ModelGenerator.csproj | 4 +- .../Options/ArgHelpers.cs | 119 ++++++++++++++ .../Options/ArgMappingsRegister.cs | 54 ++++++ .../Options/UsedMappings.cs | 18 ++ .../Options/UsedMappingsType.cs | 8 + .../{ => Options}/UsedSdkInfo.cs | 2 +- .../{ => Options}/ValidationExtensions.cs | 2 +- src/Kontent.Ai.ModelGenerator/Program.cs | 11 +- .../ArgHelpersTests.cs | 154 +++++++++++++++--- .../UsedSdkInfoTests.cs | 2 +- .../ValidationExtensionsTests.cs | 1 + 12 files changed, 347 insertions(+), 126 deletions(-) delete mode 100644 src/Kontent.Ai.ModelGenerator/ArgHelpers.cs create mode 100644 src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs create mode 100644 src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs create mode 100644 src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs create mode 100644 src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs rename src/Kontent.Ai.ModelGenerator/{ => Options}/UsedSdkInfo.cs (91%) rename src/Kontent.Ai.ModelGenerator/{ => Options}/ValidationExtensions.cs (98%) diff --git a/src/Kontent.Ai.ModelGenerator/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/ArgHelpers.cs deleted file mode 100644 index 9c70797f..00000000 --- a/src/Kontent.Ai.ModelGenerator/ArgHelpers.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Kontent.Ai.Delivery.Abstractions; -using Kontent.Ai.Management.Configuration; -using Kontent.Ai.ModelGenerator.Core.Configuration; - -namespace Kontent.Ai.ModelGenerator; - -internal static class ArgHelpers -{ - private static readonly ProgramOptionsData ManagementProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), "management-sdk-net"); - private static readonly ProgramOptionsData DeliveryProgramOptionsData = new ProgramOptionsData(typeof(DeliveryOptions), "delivery-sdk-net"); - - private static readonly IDictionary GeneralMappings = new Dictionary - { - { "-n", nameof(CodeGeneratorOptions.Namespace) }, - { "-o", nameof(CodeGeneratorOptions.OutputDir) }, - { "-f", nameof(CodeGeneratorOptions.FileNameSuffix) }, - { "-g", nameof(CodeGeneratorOptions.GeneratePartials) }, - { "-b", nameof(CodeGeneratorOptions.BaseClass) } - }; - private static readonly IDictionary DeliveryMappings = new Dictionary - { - { "-p", $"{DeliveryProgramOptionsData.OptionsName}:{nameof(DeliveryOptions.ProjectId)}" }, - {"--projectid", $"{DeliveryProgramOptionsData.OptionsName}:{nameof(DeliveryOptions.ProjectId)}" }, // Backwards compatibility - { "-s", nameof(CodeGeneratorOptions.StructuredModel) }, - { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) } - }; - private static readonly IDictionary ManagementMappings = new Dictionary - { - { "-p", $"{ManagementProgramOptionsData.OptionsName}:{nameof(ManagementOptions.ProjectId)}" }, - {"--projectid", $"{ManagementProgramOptionsData.OptionsName}:{nameof(ManagementOptions.ProjectId)}" }, // Backwards compatibility - { "-m", nameof(CodeGeneratorOptions.ManagementApi) }, - { "-k", $"{ManagementProgramOptionsData.OptionsName}:{nameof(ManagementOptions.ApiKey)}" }, - { "--apikey", $"{ManagementProgramOptionsData.OptionsName}:{nameof(ManagementOptions.ApiKey)}" } // Backwards compatibility - }; - - private static readonly IEnumerable AllMappingsKeys = GeneralMappings.Keys.Union(DeliveryMappings.Keys).Union(ManagementMappings.Keys); - - public static IDictionary GetSwitchMappings(string[] args) - { - return GeneralMappings - .Union(ContainsManageApiArg() ? ManagementMappings : DeliveryMappings) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - - bool ContainsManageApiArg() => - args.Where((value, index) => value is "-m" or "--managementapi" && index + 1 < args.Length && args[index + 1] == "true").Any(); - } - - public static bool ContainsValidArgs(string[] args) - { - var containsValidArgs = true; - var codeGeneratorOptionsProperties = typeof(CodeGeneratorOptions).GetProperties() - .Where(p => p.PropertyType != ManagementProgramOptionsData.Type && p.PropertyType != DeliveryProgramOptionsData.Type) - .Select(p => p.Name.ToLower()) - .ToList(); - - foreach (var arg in args.Where(a => - a.StartsWith('-') && - !AllMappingsKeys.Contains(a) && - !IsOptionPropertyValid(ManagementProgramOptionsData, a) && - !IsOptionPropertyValid(DeliveryProgramOptionsData, a) && - !IsOptionPropertyValid(codeGeneratorOptionsProperties, a))) - { - Console.Error.WriteLine($"Unsupported parameter: {arg}"); - containsValidArgs = false; - } - - return containsValidArgs; - } - - public static UsedSdkInfo GetUsedSdkInfo(bool managementApi) => - managementApi ? ManagementProgramOptionsData.UsedSdkInfo : DeliveryProgramOptionsData.UsedSdkInfo; - - private static bool IsOptionPropertyValid(ProgramOptionsData programOptionsData, string arg) => - IsOptionPropertyValid(programOptionsData.OptionProperties.Select(prop => $"{programOptionsData.OptionsName}:{prop.Name}"), arg); - - private static bool IsOptionPropertyValid(IEnumerable optionProperties, string arg) => - optionProperties.Any(prop => $"--{prop}" == arg); - - private class ProgramOptionsData - { - public IEnumerable OptionProperties { get; } - public string OptionsName { get; } - public UsedSdkInfo UsedSdkInfo { get; set; } - public Type Type { get; } - - public ProgramOptionsData(Type type, string sdkName) - { - UsedSdkInfo = new UsedSdkInfo(type, sdkName); - Type = type; - OptionProperties = type.GetProperties(); - OptionsName = type.Name; - } - } -} diff --git a/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj b/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj index cae0c151..f8a23c14 100644 --- a/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj +++ b/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj @@ -42,8 +42,8 @@ - - + + diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs new file mode 100644 index 00000000..afbca5c1 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Kontent.Ai.Delivery.Abstractions; +using Kontent.Ai.Management.Configuration; +using Kontent.Ai.ModelGenerator.Core.Configuration; + +namespace Kontent.Ai.ModelGenerator.Options; + +internal static class ArgHelpers +{ + private static readonly ProgramOptionsData ManagementProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), "management-sdk-net"); + private static readonly ProgramOptionsData DeliveryProgramOptionsData = new ProgramOptionsData(typeof(DeliveryOptions), "delivery-sdk-net"); + private static readonly ProgramOptionsData ExtendedDeliveryProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), typeof(DeliveryOptions), "delivery-sdk-net"); + + public static UsedMappings GetSwitchMappings(string[] args) + { + var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); + var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); + var extendedDeliverPreviewDecidingArgs = new DecidingArgs("-r", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels))); + + for (var i = 0; i < args.Length; i++) + { + if (i + 1 >= args.Length || args[i + 1] != "true") continue; + + if (args[i] == managementDecidingArgs.ShorthandedArgName || args[i] == managementDecidingArgs.FullArgName) + { + return new UsedMappings(ArgMappingsRegister.ManagementMappings, UsedMappingsType.Management); + } + + if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || + args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) + { + return new UsedMappings(ArgMappingsRegister.ExtendedDeliveryMappings, UsedMappingsType.ExtendedDelivery); + } + } + + return new UsedMappings(ArgMappingsRegister.DeliveryMappings, UsedMappingsType.Delivery); + } + + public static bool ContainsValidArgs(string[] args) + { + var containsValidArgs = true; + var codeGeneratorOptionsProperties = typeof(CodeGeneratorOptions).GetProperties() + .Where(p => + p.PropertyType != ManagementProgramOptionsData.Type && + p.PropertyType != DeliveryProgramOptionsData.Type && + p.PropertyType != ExtendedDeliveryProgramOptionsData.Type) + .Select(p => p.Name.ToLower()) + .ToList(); + + foreach (var arg in args.Where(a => + a.StartsWith('-') && + !ArgMappingsRegister.AllMappingsKeys.Contains(a) && + !IsOptionPropertyValid(ManagementProgramOptionsData, a) && + !IsOptionPropertyValid(DeliveryProgramOptionsData, a) && + !IsOptionPropertyValid(ExtendedDeliveryProgramOptionsData, a) && + !IsOptionPropertyValid(codeGeneratorOptionsProperties, a))) + { + Console.Error.WriteLine($"Unsupported parameter: {arg}"); + containsValidArgs = false; + } + + return containsValidArgs; + } + + public static UsedSdkInfo GetUsedSdkInfo(UsedMappingsType usedMappingsType) => usedMappingsType switch + { + UsedMappingsType.Delivery => DeliveryProgramOptionsData.UsedSdkInfo, + UsedMappingsType.Management => ManagementProgramOptionsData.UsedSdkInfo, + UsedMappingsType.ExtendedDelivery => ExtendedDeliveryProgramOptionsData.UsedSdkInfo, + _ => throw new ArgumentOutOfRangeException(nameof(usedMappingsType)) + }; + + private static bool IsOptionPropertyValid(ProgramOptionsData programOptionsData, string arg) => + IsOptionPropertyValid(programOptionsData.OptionProperties.Select(prop => $"{programOptionsData.OptionsName}:{prop.Name}"), arg); + + private static bool IsOptionPropertyValid(IEnumerable optionProperties, string arg) => + optionProperties.Any(prop => GetPrefixedMappingName(prop, false) == arg); + + private static string GetPrefixedMappingName(string mappingName, bool toLower = true) => $"--{(toLower ? mappingName.ToLower() : mappingName)}"; + + private class ProgramOptionsData + { + public IEnumerable OptionProperties { get; } + public string OptionsName { get; } + public UsedSdkInfo UsedSdkInfo { get; set; } + public Type Type { get; } + + public ProgramOptionsData(Type type, string sdkName) + { + UsedSdkInfo = new UsedSdkInfo(type, sdkName); + Type = type; + OptionProperties = type.GetProperties(); + OptionsName = type.Name; + } + + public ProgramOptionsData(Type optionsType, Type sdkType, string sdkName) + { + UsedSdkInfo = new UsedSdkInfo(sdkType, sdkName); + Type = optionsType; + OptionProperties = optionsType.GetProperties(); + OptionsName = optionsType.Name; + } + } + + private class DecidingArgs + { + public string ShorthandedArgName { get; } + public string FullArgName { get; } + + public DecidingArgs(string shorthandedArgName, string fullArgName) + { + ShorthandedArgName = shorthandedArgName; + FullArgName = fullArgName; + } + } +} diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs new file mode 100644 index 00000000..f577b177 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Linq; +using Kontent.Ai.Delivery.Abstractions; +using Kontent.Ai.Management.Configuration; +using Kontent.Ai.ModelGenerator.Core.Configuration; + +namespace Kontent.Ai.ModelGenerator.Options; + +internal class ArgMappingsRegister +{ + public static readonly IDictionary GeneralMappings = new Dictionary + { + { "-n", nameof(CodeGeneratorOptions.Namespace) }, + { "-o", nameof(CodeGeneratorOptions.OutputDir) }, + { "-f", nameof(CodeGeneratorOptions.FileNameSuffix) }, + { "-g", nameof(CodeGeneratorOptions.GeneratePartials) }, + { "-b", nameof(CodeGeneratorOptions.BaseClass) } + }; + + public static readonly IDictionary DeliveryMappings = new Dictionary + { + { "-p", $"{nameof(DeliveryOptions)}:{nameof(DeliveryOptions.ProjectId)}" }, + {"--projectid", $"{nameof(DeliveryOptions)}:{nameof(DeliveryOptions.ProjectId)}" }, // Backwards compatibility + { "-s", nameof(CodeGeneratorOptions.StructuredModel) }, + { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) } + }; + + public static readonly IDictionary ExtendedDeliveryMappings = new Dictionary + { + { "-p", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ProjectId)}" }, + {"--projectid", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ProjectId)}" }, // Backwards compatibility + { "-s", nameof(CodeGeneratorOptions.StructuredModel) }, + { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) }, + { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, + { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, + { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, + { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } + }; + + public static readonly IDictionary ManagementMappings = new Dictionary + { + { "-p", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ProjectId)}" }, + {"--projectid", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ProjectId)}" }, // Backwards compatibility + { "-m", nameof(CodeGeneratorOptions.ManagementApi) }, + { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, + { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" } // Backwards compatibility + }; + + public static readonly IEnumerable AllMappingsKeys = + GeneralMappings.Keys + .Union(DeliveryMappings.Keys) + .Union(ManagementMappings.Keys) + .Union(ExtendedDeliveryMappings.Keys); +} \ No newline at end of file diff --git a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs new file mode 100644 index 00000000..4c7ae1dc --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Kontent.Ai.ModelGenerator.Options; + +internal class UsedMappings +{ + public IDictionary Mappings { get; } + public UsedMappingsType UsedMappingsType { get; } + + public UsedMappings(IDictionary mappings, UsedMappingsType usedMappingsType) + { + Mappings = ArgMappingsRegister.GeneralMappings + .Union(mappings) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + UsedMappingsType = usedMappingsType; + } +} diff --git a/src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs new file mode 100644 index 00000000..e5337004 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs @@ -0,0 +1,8 @@ +namespace Kontent.Ai.ModelGenerator.Options; + +internal enum UsedMappingsType +{ + Delivery, + Management, + ExtendedDelivery +} diff --git a/src/Kontent.Ai.ModelGenerator/UsedSdkInfo.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedSdkInfo.cs similarity index 91% rename from src/Kontent.Ai.ModelGenerator/UsedSdkInfo.cs rename to src/Kontent.Ai.ModelGenerator/Options/UsedSdkInfo.cs index 54bc0edf..dc8da675 100644 --- a/src/Kontent.Ai.ModelGenerator/UsedSdkInfo.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/UsedSdkInfo.cs @@ -1,7 +1,7 @@ using System; using System.Reflection; -namespace Kontent.Ai.ModelGenerator; +namespace Kontent.Ai.ModelGenerator.Options; internal class UsedSdkInfo { diff --git a/src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs b/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs similarity index 98% rename from src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs rename to src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs index 3380a659..bd648515 100644 --- a/src/Kontent.Ai.ModelGenerator/ValidationExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs @@ -4,7 +4,7 @@ using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; -namespace Kontent.Ai.ModelGenerator; +namespace Kontent.Ai.ModelGenerator.Options; /// /// Extension methods meant for validation. diff --git a/src/Kontent.Ai.ModelGenerator/Program.cs b/src/Kontent.Ai.ModelGenerator/Program.cs index 4437e7d8..55880e7d 100644 --- a/src/Kontent.Ai.ModelGenerator/Program.cs +++ b/src/Kontent.Ai.ModelGenerator/Program.cs @@ -8,6 +8,7 @@ using Kontent.Ai.Delivery.Extensions; using Kontent.Ai.ModelGenerator.Core; using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Options; namespace Kontent.Ai.ModelGenerator; @@ -26,11 +27,13 @@ public static async Task Main(string[] args) return 1; } + var usedMappings = ArgHelpers.GetSwitchMappings(args); + // Build a configuration object from given sources var configuration = new ConfigurationBuilder() .SetBasePath(Environment.CurrentDirectory) .AddJsonFile("appSettings.json", true) - .AddCommandLine(args, ArgHelpers.GetSwitchMappings(args)) + .AddCommandLine(args, usedMappings.Mappings) .Build(); // Fill the DI container @@ -49,7 +52,7 @@ public static async Task Main(string[] args) var options = serviceProvider.GetService>().Value; options.Validate(); - PrintSdkVersion(options); + PrintSdkVersion(usedMappings); // Code generator entry point if (options.ManagementApi()) @@ -77,9 +80,9 @@ public static async Task Main(string[] args) private static async Task WriteErrorMessageAsync(string message) => await Console.Error.WriteLineAsync(message); - private static void PrintSdkVersion(CodeGeneratorOptions options) + private static void PrintSdkVersion(UsedMappings usedMappings) { - var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(options.ManagementApi()); + var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(usedMappings.UsedMappingsType); Console.WriteLine($"Models were generated for {usedSdkInfo.Name} version {usedSdkInfo.Version}"); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index 9e6643a7..af176a50 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -5,6 +5,7 @@ using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Options; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests; @@ -34,7 +35,7 @@ public class ArgHelpersTests { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" } }; - private static IDictionary ExpectedDeliveryMappings => new Dictionary + private static IDictionary ExpectedExtendedDeliveryMappings => new Dictionary { { "-n", nameof(CodeGeneratorOptions.Namespace) }, { "-o", nameof(CodeGeneratorOptions.OutputDir) }, @@ -42,27 +43,45 @@ public class ArgHelpersTests { "-g", nameof(CodeGeneratorOptions.GeneratePartials) }, { "-s", nameof(CodeGeneratorOptions.StructuredModel) }, { "-b", nameof(CodeGeneratorOptions.BaseClass) }, - { "-p", $"{nameof(DeliveryOptions)}:{nameof(DeliveryOptions.ProjectId)}" }, - { "--projectid", $"{nameof(DeliveryOptions)}:{nameof(DeliveryOptions.ProjectId)}" }, - { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) } + { "-p", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ProjectId)}" }, + {"--projectid", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ProjectId)}" }, + { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) }, + { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, + { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, + { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, + { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } }; + private static IDictionary ExpectedDeliveryMappings => new Dictionary + { + { "-n", nameof(CodeGeneratorOptions.Namespace) }, + { "-o", nameof(CodeGeneratorOptions.OutputDir) }, + { "-f", nameof(CodeGeneratorOptions.FileNameSuffix) }, + { "-g", nameof(CodeGeneratorOptions.GeneratePartials) }, + { "-s", nameof(CodeGeneratorOptions.StructuredModel) }, + { "-b", nameof(CodeGeneratorOptions.BaseClass) }, + { "-p", $"{nameof(DeliveryOptions)}:{nameof(DeliveryOptions.ProjectId)}" }, + { "--projectid", $"{nameof(DeliveryOptions)}:{nameof(DeliveryOptions.ProjectId)}" }, + { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) } + }; + [Fact] public void GetSwitchMappings_MissingMapiSwitch_ReturnsDeliveryMappings() { - var mappings = ArgHelpers.GetSwitchMappings(new string[] + var result = ArgHelpers.GetSwitchMappings(new string[] { "-p", Guid.NewGuid().ToString() }); - Assert.Equal(ExpectedDeliveryMappings, mappings); + Assert.Equal(ExpectedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.Delivery, result.UsedMappingsType); } [Fact] public void GetSwitchMappings_MapiSwitchIsFalse_ReturnsDeliveryMappings() { - var mappings = ArgHelpers.GetSwitchMappings(new string[] + var result = ArgHelpers.GetSwitchMappings(new string[] { "-p", Guid.NewGuid().ToString(), @@ -70,13 +89,14 @@ public void GetSwitchMappings_MapiSwitchIsFalse_ReturnsDeliveryMappings() "false" }); - Assert.Equal(ExpectedDeliveryMappings, mappings); + Assert.Equal(ExpectedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.Delivery, result.UsedMappingsType); } [Fact] public void GetSwitchMappings_MapiSwitchIsTrue_ReturnsManagementMappings() { - var mappings = ArgHelpers.GetSwitchMappings(new string[] + var result = ArgHelpers.GetSwitchMappings(new string[] { "-p", Guid.NewGuid().ToString(), @@ -84,7 +104,55 @@ public void GetSwitchMappings_MapiSwitchIsTrue_ReturnsManagementMappings() "true" }); - Assert.Equal(ExpectedManagementMappings, mappings); + Assert.Equal(ExpectedManagementMappings, result.Mappings); + Assert.Equal(UsedMappingsType.Management, result.UsedMappingsType); + } + + [Fact] + public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() + { + var result = ArgHelpers.GetSwitchMappings(new string[] + { + "-p", + Guid.NewGuid().ToString(), + "-e", + "true" + }); + + Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + } + + [Fact] + public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMappings() + { + var result = ArgHelpers.GetSwitchMappings(new string[] + { + "-p", + Guid.NewGuid().ToString(), + "-r", + "true" + }); + + Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + } + + [Fact] + public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagementMappings() + { + var result = ArgHelpers.GetSwitchMappings(new string[] + { + "-p", + Guid.NewGuid().ToString(), + "-e", + "true", + "-r", + "true" + }); + + Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); } [Fact] @@ -114,9 +182,9 @@ public void ContainsContainsValidArgs_UnsupportedDeliveryOptions_ReturnsFalse(st { var args = new[] { - arg, - "arg_value" - }; + arg, + "arg_value" + }; var result = ArgHelpers.ContainsValidArgs(args); Assert.False(result); @@ -128,7 +196,7 @@ public void ContainsContainsValidArgs_SupportedManagementOptions_ReturnsTrue() var args = AppendValuesToArgs(ExpectedManagementMappings) .Concat(AppendValuesToArgs(ToLower(new List { - nameof(CodeGeneratorOptions.ManagementApi) + nameof(CodeGeneratorOptions.ManagementApi) }))) .Concat(AppendValuesToArgs(GeneralOptionArgs)) .Concat(AppendValuesToArgs(typeof(ManagementOptions))) @@ -149,9 +217,48 @@ public void ContainsContainsValidArgs_UnsupportedManagementOptions_ReturnsFalse( { var args = new[] { - arg, - "arg_value" - }; + arg, + "arg_value" + }; + var result = ArgHelpers.ContainsValidArgs(args); + + Assert.False(result); + } + + [Fact] + public void ContainsContainsValidArgs_SupportedExtendedDeliveryOptions_ReturnsTrue() + { + var args = AppendValuesToArgs(ExpectedExtendedDeliveryMappings) + .Concat(AppendValuesToArgs(ToLower(new List + { + nameof(CodeGeneratorOptions.StructuredModel), + nameof(CodeGeneratorOptions.WithTypeProvider) + }))) + .Concat(AppendValuesToArgs(GeneralOptionArgs)) + .Concat(AppendValuesToArgs(typeof(ManagementOptions))) + .ToArray(); + + var result = ArgHelpers.ContainsValidArgs(args); + + Assert.True(result); + } + + [Theory] + [InlineData("-x")] + [InlineData("--contentmanagementapi")] + [InlineData("--managementapix")] + [InlineData("--ManagementOptions:ApiKeyX")] + [InlineData("--ManagementOptionsX:ApiKey")] + [InlineData("--DeliveryOptionsX:UseSecureAccess")] + [InlineData("--DeliveryOptions:UseSecureAccessX")] + public void ContainsContainsValidArgs_UnsupportedExtendedDeliveryOptions_ReturnsFalse(string arg) + { + var args = new[] + { + arg, + "arg_value" + }; + var result = ArgHelpers.ContainsValidArgs(args); Assert.False(result); @@ -160,7 +267,7 @@ public void ContainsContainsValidArgs_UnsupportedManagementOptions_ReturnsFalse( [Fact] public void GetProgramOptionsData_ManagementApi_ReturnsManagementProgramOptionsData() { - var result = ArgHelpers.GetUsedSdkInfo(true); + var result = ArgHelpers.GetUsedSdkInfo(UsedMappingsType.Management); Assert.Equal("management-sdk-net", result.Name); Assert.Equal(Assembly.GetAssembly(typeof(ManagementOptions)).GetName().Version.ToString(3), result.Version); @@ -169,7 +276,16 @@ public void GetProgramOptionsData_ManagementApi_ReturnsManagementProgramOptionsD [Fact] public void GetProgramOptionsData_DeliveryApi_ReturnsDeliveryProgramOptionsData() { - var result = ArgHelpers.GetUsedSdkInfo(false); + var result = ArgHelpers.GetUsedSdkInfo(UsedMappingsType.Delivery); + + Assert.Equal("delivery-sdk-net", result.Name); + Assert.Equal(Assembly.GetAssembly(typeof(DeliveryOptions)).GetName().Version.ToString(3), result.Version); + } + + [Fact] + public void GetProgramOptionsData_ExtendedDeliveryApi_ReturnsExtendedDeliveryProgramOptionsData() + { + var result = ArgHelpers.GetUsedSdkInfo(UsedMappingsType.ExtendedDelivery); Assert.Equal("delivery-sdk-net", result.Name); Assert.Equal(Assembly.GetAssembly(typeof(DeliveryOptions)).GetName().Version.ToString(3), result.Version); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs index 949575b1..7a8f803f 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs @@ -1,5 +1,5 @@ using System; -using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Options; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests; diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs index f9e860a4..09b5f426 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs @@ -2,6 +2,7 @@ using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Options; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests; From 2844427c8977c6388fe32562bf5f1ff16213e977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Sat, 10 Sep 2022 22:21:27 +0200 Subject: [PATCH 04/48] 90 remove preview option --- .../Configuration/CodeGeneratorOptions.cs | 5 --- .../CodeGeneratorOptionsExtensions.cs | 2 +- .../Options/ArgHelpers.cs | 4 +-- .../Options/ArgMappingsRegister.cs | 1 - .../ArgHelpersTests.cs | 33 ------------------- .../CodeGeneratorOptionsExtensionsTests.cs | 24 +++++--------- 6 files changed, 10 insertions(+), 59 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs index 92cc5e53..3684eb40 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs @@ -28,11 +28,6 @@ public class CodeGeneratorOptions /// public bool ExtendedDeliverModels { get; set; } = DefaultExtendedDeliverModels; - /// - /// Indicates whether the extended preview Delivery models should be generated - /// - public bool ExtendedDeliverPreviewModels { get; set; } = DefaultExtendedDeliverPreviewModels; - /// /// Namespace name of the generated classes /// diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index e394af9b..5ec77b84 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -3,5 +3,5 @@ public static class CodeGeneratorOptionsExtensions { public static bool ManagementApi(this CodeGeneratorOptions options) => - options.ManagementApi && !options.ExtendedDeliverModels && !options.ExtendedDeliverPreviewModels; + options.ManagementApi && !options.ExtendedDeliverModels; } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index afbca5c1..a738ff6e 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -18,7 +18,6 @@ public static UsedMappings GetSwitchMappings(string[] args) { var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); - var extendedDeliverPreviewDecidingArgs = new DecidingArgs("-r", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels))); for (var i = 0; i < args.Length; i++) { @@ -29,8 +28,7 @@ public static UsedMappings GetSwitchMappings(string[] args) return new UsedMappings(ArgMappingsRegister.ManagementMappings, UsedMappingsType.Management); } - if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || - args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) + if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName) { return new UsedMappings(ArgMappingsRegister.ExtendedDeliveryMappings, UsedMappingsType.ExtendedDelivery); } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs index f577b177..df32c9c0 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs @@ -34,7 +34,6 @@ internal class ArgMappingsRegister { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, - { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } }; public static readonly IDictionary ManagementMappings = new Dictionary diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index af176a50..3e6f07cd 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -49,7 +49,6 @@ public class ArgHelpersTests { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, - { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } }; private static IDictionary ExpectedDeliveryMappings => new Dictionary @@ -123,38 +122,6 @@ public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); } - [Fact] - public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMappings() - { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-r", - "true" - }); - - Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); - } - - [Fact] - public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagementMappings() - { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-e", - "true", - "-r", - "true" - }); - - Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); - } - [Fact] public void ContainsContainsValidArgs_SupportedDeliveryOptions_ReturnsTrue() { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index 6c3674c4..aecb85b4 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -11,8 +11,7 @@ public void ManagementApi_ManagementApi_ReturnsTrue() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.ManagementApi(); @@ -21,17 +20,14 @@ public void ManagementApi_ManagementApi_ReturnsTrue() } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [InlineData(true)] + [InlineData(false)] + public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels) { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = extendedDeliverModels }; var result = options.ManagementApi(); @@ -39,17 +35,13 @@ public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverMode Assert.False(result); } - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [Fact] + public void ManagementApi_InvalidConfig_ReturnsFalse() { var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = options.ManagementApi(); From cf20f7bd53daeee8f6f8d73f2744f7bf2a11940b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 15 Sep 2022 11:11:59 +0200 Subject: [PATCH 05/48] Revert "90 remove preview option" This reverts commit 2844427c8977c6388fe32562bf5f1ff16213e977. --- .../Configuration/CodeGeneratorOptions.cs | 5 +++ .../CodeGeneratorOptionsExtensions.cs | 2 +- .../Options/ArgHelpers.cs | 4 ++- .../Options/ArgMappingsRegister.cs | 1 + .../ArgHelpersTests.cs | 33 +++++++++++++++++++ .../CodeGeneratorOptionsExtensionsTests.cs | 24 +++++++++----- 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs index 3684eb40..92cc5e53 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs @@ -28,6 +28,11 @@ public class CodeGeneratorOptions /// public bool ExtendedDeliverModels { get; set; } = DefaultExtendedDeliverModels; + /// + /// Indicates whether the extended preview Delivery models should be generated + /// + public bool ExtendedDeliverPreviewModels { get; set; } = DefaultExtendedDeliverPreviewModels; + /// /// Namespace name of the generated classes /// diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index 5ec77b84..e394af9b 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -3,5 +3,5 @@ public static class CodeGeneratorOptionsExtensions { public static bool ManagementApi(this CodeGeneratorOptions options) => - options.ManagementApi && !options.ExtendedDeliverModels; + options.ManagementApi && !options.ExtendedDeliverModels && !options.ExtendedDeliverPreviewModels; } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index a738ff6e..afbca5c1 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -18,6 +18,7 @@ public static UsedMappings GetSwitchMappings(string[] args) { var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); + var extendedDeliverPreviewDecidingArgs = new DecidingArgs("-r", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels))); for (var i = 0; i < args.Length; i++) { @@ -28,7 +29,8 @@ public static UsedMappings GetSwitchMappings(string[] args) return new UsedMappings(ArgMappingsRegister.ManagementMappings, UsedMappingsType.Management); } - if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName) + if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || + args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) { return new UsedMappings(ArgMappingsRegister.ExtendedDeliveryMappings, UsedMappingsType.ExtendedDelivery); } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs index df32c9c0..f577b177 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs @@ -34,6 +34,7 @@ internal class ArgMappingsRegister { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, + { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } }; public static readonly IDictionary ManagementMappings = new Dictionary diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index 3e6f07cd..af176a50 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -49,6 +49,7 @@ public class ArgHelpersTests { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, + { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } }; private static IDictionary ExpectedDeliveryMappings => new Dictionary @@ -122,6 +123,38 @@ public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); } + [Fact] + public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMappings() + { + var result = ArgHelpers.GetSwitchMappings(new string[] + { + "-p", + Guid.NewGuid().ToString(), + "-r", + "true" + }); + + Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + } + + [Fact] + public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagementMappings() + { + var result = ArgHelpers.GetSwitchMappings(new string[] + { + "-p", + Guid.NewGuid().ToString(), + "-e", + "true", + "-r", + "true" + }); + + Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); + Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + } + [Fact] public void ContainsContainsValidArgs_SupportedDeliveryOptions_ReturnsTrue() { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index aecb85b4..6c3674c4 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -11,7 +11,8 @@ public void ManagementApi_ManagementApi_ReturnsTrue() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false }; var result = options.ManagementApi(); @@ -20,14 +21,17 @@ public void ManagementApi_ManagementApi_ReturnsTrue() } [Theory] - [InlineData(true)] - [InlineData(false)] - public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels) + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels }; var result = options.ManagementApi(); @@ -35,13 +39,17 @@ public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverMode Assert.False(result); } - [Fact] - public void ManagementApi_InvalidConfig_ReturnsFalse() + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) { var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = true + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels }; var result = options.ManagementApi(); From 8495ecaa7fb13a6e49f4db9d422755fe2a8bb253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 15 Sep 2022 11:20:32 +0200 Subject: [PATCH 06/48] 90 options validation --- .../CodeGeneratorOptionsExtensions.cs | 15 ++ .../Configuration/UsedMappingsType.cs | 8 + .../Options/UsedMappings.cs | 1 + .../Options/UsedMappingsType.cs | 8 - .../Options/ValidationExtensions.cs | 57 ++++-- .../CodeGeneratorOptionsExtensionsTests.cs | 183 ++++++++++++++++++ .../ValidationExtensionsTests.cs | 173 +++++++++++++---- 7 files changed, 378 insertions(+), 67 deletions(-) create mode 100644 src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs delete mode 100644 src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index e394af9b..897a62a7 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -4,4 +4,19 @@ public static class CodeGeneratorOptionsExtensions { public static bool ManagementApi(this CodeGeneratorOptions options) => options.ManagementApi && !options.ExtendedDeliverModels && !options.ExtendedDeliverPreviewModels; + + public static bool ExtendedDeliveryModels(this CodeGeneratorOptions options) => + !options.ManagementApi && (options.ExtendedDeliverModels || options.ExtendedDeliverPreviewModels); + + public static bool DeliveryApi(this CodeGeneratorOptions options) => !options.ManagementApi() && !options.ExtendedDeliveryModels(); + + public static UsedMappingsType GetUsedMappingsType(this CodeGeneratorOptions options) + { + if (options.ManagementApi()) + { + return UsedMappingsType.Management; + } + + return options.ExtendedDeliveryModels() ? UsedMappingsType.ExtendedDelivery : UsedMappingsType.Delivery; + } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs new file mode 100644 index 00000000..5ec57c45 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs @@ -0,0 +1,8 @@ +namespace Kontent.Ai.ModelGenerator.Core.Configuration; + +public enum UsedMappingsType +{ + Delivery, + Management, + ExtendedDelivery +} diff --git a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs index 4c7ae1dc..cdd5b7f2 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Kontent.Ai.ModelGenerator.Core.Configuration; namespace Kontent.Ai.ModelGenerator.Options; diff --git a/src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs deleted file mode 100644 index e5337004..00000000 --- a/src/Kontent.Ai.ModelGenerator/Options/UsedMappingsType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Kontent.Ai.ModelGenerator.Options; - -internal enum UsedMappingsType -{ - Delivery, - Management, - ExtendedDelivery -} diff --git a/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs b/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs index bd648515..b433a63e 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs @@ -11,56 +11,75 @@ namespace Kontent.Ai.ModelGenerator.Options; /// public static class ValidationExtensions { - private const string DeliveryParamsLink = "http://bit.ly/k-params"; - private const string ManagementParamsLink = "https://bit.ly/3rSMeDA"; - private static string SeePart(bool managementApi) => $"See {(managementApi ? ManagementParamsLink : DeliveryParamsLink)} for more details on configuration."; - /// /// Validates that CodeGeneratorOptions are initialized and performs some extra integrity validations. /// /// CodeGeneratorOptions object to be validated public static void Validate(this CodeGeneratorOptions codeGeneratorOptions) { - if (codeGeneratorOptions.ManagementApi) + var usedMappingsType = codeGeneratorOptions.GetUsedMappingsType(); + if (usedMappingsType == UsedMappingsType.Delivery) { - codeGeneratorOptions.ManagementOptions.Validate(); + codeGeneratorOptions.DeliveryOptionsValidate(); } else { - codeGeneratorOptions.DeliveryOptions.Validate(); + codeGeneratorOptions.ManagementOptionsValidate(); } } /// /// Validates that ManagementOptions are initialized /// - /// ManagementOptions object to be validated + /// CodeGeneratorOptions object including ManagementOptions object to be validated /// - private static void Validate(this ManagementOptions managementOptions) + private static void ManagementOptionsValidate(this CodeGeneratorOptions codeGeneratorOptions) { - var seePart = SeePart(true); - if (managementOptions?.ProjectId == null) + if (codeGeneratorOptions.ManagementOptions?.ProjectId == null) { - throw new Exception($"You have to provide the '{nameof(ManagementOptions.ProjectId)}' to generate type for Management SDK. {seePart}"); + throw new Exception(ExceptionMessage(codeGeneratorOptions, nameof(ManagementOptions.ProjectId))); } - if (string.IsNullOrWhiteSpace(managementOptions.ApiKey)) + if (string.IsNullOrWhiteSpace(codeGeneratorOptions.ManagementOptions.ApiKey)) { - throw new Exception($"You have to provide the '{nameof(ManagementOptions.ApiKey)}' to generate type for Management SDK. {seePart}"); + throw new Exception(ExceptionMessage(codeGeneratorOptions, nameof(ManagementOptions.ApiKey))); } } /// /// Validates that DeliveryOptions are initialized and performs some extra integrity validations. /// - /// DeliveryOptions object to be validated - private static void Validate(this DeliveryOptions deliveryOptions) + /// CodeGeneratorOptions object including DeliveryOptions object to be validated + private static void DeliveryOptionsValidate(this CodeGeneratorOptions codeGeneratorOptions) { - if (deliveryOptions == null) + if (codeGeneratorOptions.DeliveryOptions == null) { - throw new Exception($"You have to provide at least the '{nameof(DeliveryOptions.ProjectId)}' argument. {SeePart(false)}"); + throw new Exception(ExceptionMessage(codeGeneratorOptions, nameof(DeliveryOptions.ProjectId))); } - DeliveryOptionsValidator.Validate(deliveryOptions); + codeGeneratorOptions.DeliveryOptions.Validate(); + } + + private static string ExceptionMessage(CodeGeneratorOptions options, string argName) + { + var atLeastPrefix = options.DeliveryApi() ? " at least " : " "; + var sdkNameInfo = $"to generate type for {(options.ExtendedDeliveryModels() ? "Delivery" : "Management")} SDK"; + var argInfo = options.DeliveryApi() ? "argument" : sdkNameInfo; + var seePart = SeePart(); + + return $"You have to provide{atLeastPrefix}the '{argName}' {argInfo}. {seePart}"; + + string SeePart() + { + var paramsLink = options.GetUsedMappingsType() switch + { + UsedMappingsType.Management => "https://bit.ly/3rSMeDA", + UsedMappingsType.Delivery => "http://bit.ly/k-params", + UsedMappingsType.ExtendedDelivery => "https://bit.ly/3rSMeDA",//todo provide proper link to docs + _ => throw new ArgumentOutOfRangeException() + }; + + return $"See {paramsLink} for more details on configuration."; + } } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index 6c3674c4..31afa536 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -56,4 +56,187 @@ public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, Assert.False(result); } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = options.ExtendedDeliveryModels(); + + Assert.False(result); + } + + [Fact] + public void ExtendedDeliveryModels_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsFalse() + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }; + + var result = options.ExtendedDeliveryModels(); + + Assert.False(result); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + public void ExtendedDeliveryModels_ManagementApiIsFalse_ReturnsTrue(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = options.ExtendedDeliveryModels(); + + Assert.True(result); + } + + [Fact] + public void DeliveryApi_DefaultOptions_ReturnsTrue() + { + var options = new CodeGeneratorOptions(); + + var result = options.DeliveryApi(); + + Assert.True(result); + } + + [Fact] + public void DeliveryApi_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsTrue() + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }; + + var result = options.DeliveryApi(); + + Assert.True(result); + } + + [Fact] + public void DeliveryApi_ManagementApi_ReturnsFalse() + { + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }; + + var result = options.DeliveryApi(); + + Assert.False(result); + } + + [Theory] + [InlineData(true, true)] + [InlineData(false, true)] + [InlineData(true, false)] + public void DeliveryApi_ExtendedDeliveryOptions_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = options.DeliveryApi(); + + Assert.False(result); + } + + [Fact] + public void DeliveryApi_ManagementApiIsTrue_ExtendedDeliveryOptionsAreTrue_ReturnsTrue() + { + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = true + }; + + var result = options.DeliveryApi(); + + Assert.True(result); + } + + [Fact] + public void GetUsedMappingsType_ManagementApi_ReturnsManagement() + { + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }; + + var result = options.GetUsedMappingsType(); + + Assert.Equal(UsedMappingsType.Management, result); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + public void GetUsedMappingsType_ExtendedDeliveryModels_ReturnsExtendedDelivery(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = options.GetUsedMappingsType(); + + Assert.Equal(UsedMappingsType.ExtendedDelivery, result); + } + + [Fact] + public void GetUsedMappingsType_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsDelivery() + { + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }; + + var result = options.GetUsedMappingsType(); + + Assert.Equal(UsedMappingsType.Delivery, result); + } + + [Fact] + public void GetUsedMappingsType_DefaultOptions_ReturnsDelivery() + { + var options = new CodeGeneratorOptions(); + + var result = options.GetUsedMappingsType(); + + Assert.Equal(UsedMappingsType.Delivery, result); + } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs index 09b5f426..f380be8b 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; @@ -42,6 +43,27 @@ public void Validate_DeliveryOptions_Success() codeGeneratorOptions.Validate(); } + [Theory] + [InlineData(true, false)] + [InlineData(false, true)] + public void Validate_ExtendedDeliveryModels_Success(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var projectId = Guid.NewGuid().ToString(); + var codeGeneratorOptions = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels, + ManagementOptions = new ManagementOptions + { + ProjectId = projectId, + ApiKey = "apiKey" + } + }; + + codeGeneratorOptions.Validate(); + } + [Fact] public void Validate_DeliveryOptionsIsNull_ThrowsException() { @@ -68,68 +90,139 @@ public void Validate_DeliveryOptionsProjectIdIsNull_ThrowsException() Assert.Throws(() => codeGeneratorOptions.Validate()); } - [Fact] - public void Validate_ManagementOptionsIsNull_ThrowsException() + [Theory] + [MemberData(nameof(OptionsUsingManagementApiOptionsData))] + public void Validate_ManagementOptionsIsNull_ThrowsException(CodeGeneratorOptions codeGeneratorOptions, string expectedSdkName, string expectedUrl) { var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + codeGeneratorOptions.DeliveryOptions = new DeliveryOptions { - ManagementApi = true, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - }, - ManagementOptions = null + ProjectId = projectId }; + codeGeneratorOptions.ManagementOptions = null; var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide the 'ProjectId' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); + Assert.Equal($"You have to provide the 'ProjectId' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration.", exception.Message); } - [Fact] - public void Validate_ManagementOptionsProjectIdIsNull_ThrowsException() + [Theory] + [MemberData(nameof(OptionsUsingManagementApiOptionsData))] + public void Validate_ManagementOptionsProjectIdIsNull_ThrowsException(CodeGeneratorOptions codeGeneratorOptions, string expectedSdkName, string expectedUrl) { var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + codeGeneratorOptions.DeliveryOptions = new DeliveryOptions { - ManagementApi = true, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - }, - ManagementOptions = new ManagementOptions - { - ProjectId = null, - ApiKey = "apiKey" - } + ProjectId = projectId + }; + codeGeneratorOptions.ManagementOptions = new ManagementOptions + { + ProjectId = null, + ApiKey = "apiKey" }; var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide the 'ProjectId' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); + Assert.Equal($"You have to provide the 'ProjectId' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration.", exception.Message); } [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException(string apiKey) + [MemberData(nameof(OptionsUsingManagementApiOptionsApiKeyIsNullOrWhiteSpaceData))] + public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException( + CodeGeneratorOptions codeGeneratorOptions, + string apiKey, + string expectedSdkName, + string expectedUrl) { var projectId = Guid.NewGuid().ToString(); - var codeGeneratorOptions = new CodeGeneratorOptions + codeGeneratorOptions.DeliveryOptions = new DeliveryOptions { - ManagementApi = true, - DeliveryOptions = new DeliveryOptions - { - ProjectId = projectId - }, - ManagementOptions = new ManagementOptions - { - ProjectId = projectId, - ApiKey = apiKey - } + ProjectId = projectId + }; + codeGeneratorOptions.ManagementOptions = new ManagementOptions + { + ProjectId = projectId, + ApiKey = apiKey }; var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide the 'ApiKey' to generate type for Management SDK. See https://bit.ly/3rSMeDA for more details on configuration.", exception.Message); + Assert.Equal($"You have to provide the 'ApiKey' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration.", exception.Message); } + + public static IEnumerable OptionsUsingManagementApiOptionsData => new List + { + new object[] + { + new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }, + "Management", + "https://bit.ly/3rSMeDA" + }, + new object[] + { + new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = false + }, + "Delivery", + "https://bit.ly/3rSMeDA" + }, + new object[] + { + new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = true + }, + "Delivery", + "https://bit.ly/3rSMeDA" + + } + }; + + public static IEnumerable OptionsUsingManagementApiOptionsApiKeyIsNullOrWhiteSpaceData => new List + { + new object[] + { + new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }, + null, + "Management", + "https://bit.ly/3rSMeDA" + }, + new object[] + { + new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = false + }, + "", + "Delivery", + "https://bit.ly/3rSMeDA" + }, + new object[] + { + new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = true + }, + " ", + "Delivery", + "https://bit.ly/3rSMeDA" + + } + }; } From 4e478db35fd1947033d9fc213195acd91b384d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 15 Sep 2022 15:58:23 +0200 Subject: [PATCH 07/48] 90 rename UsedMappingsType to DesiredModelsType --- .../CodeGeneratorOptionsExtensions.cs | 6 ++--- ...edMappingsType.cs => DesiredModelsType.cs} | 2 +- .../Options/ArgHelpers.cs | 16 ++++++------- .../Options/UsedMappings.cs | 6 ++--- .../Options/ValidationExtensions.cs | 12 +++++----- src/Kontent.Ai.ModelGenerator/Program.cs | 2 +- .../ArgHelpersTests.cs | 18 +++++++------- .../CodeGeneratorOptionsExtensionsTests.cs | 24 +++++++++---------- 8 files changed, 43 insertions(+), 43 deletions(-) rename src/Kontent.Ai.ModelGenerator.Core/Configuration/{UsedMappingsType.cs => DesiredModelsType.cs} (79%) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index 897a62a7..71b4f22b 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -10,13 +10,13 @@ public static bool ExtendedDeliveryModels(this CodeGeneratorOptions options) => public static bool DeliveryApi(this CodeGeneratorOptions options) => !options.ManagementApi() && !options.ExtendedDeliveryModels(); - public static UsedMappingsType GetUsedMappingsType(this CodeGeneratorOptions options) + public static DesiredModelsType GetDesiredModelsType(this CodeGeneratorOptions options) { if (options.ManagementApi()) { - return UsedMappingsType.Management; + return DesiredModelsType.Management; } - return options.ExtendedDeliveryModels() ? UsedMappingsType.ExtendedDelivery : UsedMappingsType.Delivery; + return options.ExtendedDeliveryModels() ? DesiredModelsType.ExtendedDelivery : DesiredModelsType.Delivery; } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/DesiredModelsType.cs similarity index 79% rename from src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs rename to src/Kontent.Ai.ModelGenerator.Core/Configuration/DesiredModelsType.cs index 5ec57c45..5512678b 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/UsedMappingsType.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/DesiredModelsType.cs @@ -1,6 +1,6 @@ namespace Kontent.Ai.ModelGenerator.Core.Configuration; -public enum UsedMappingsType +public enum DesiredModelsType { Delivery, Management, diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index afbca5c1..cb06455c 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -26,17 +26,17 @@ public static UsedMappings GetSwitchMappings(string[] args) if (args[i] == managementDecidingArgs.ShorthandedArgName || args[i] == managementDecidingArgs.FullArgName) { - return new UsedMappings(ArgMappingsRegister.ManagementMappings, UsedMappingsType.Management); + return new UsedMappings(ArgMappingsRegister.ManagementMappings, DesiredModelsType.Management); } if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) { - return new UsedMappings(ArgMappingsRegister.ExtendedDeliveryMappings, UsedMappingsType.ExtendedDelivery); + return new UsedMappings(ArgMappingsRegister.ExtendedDeliveryMappings, DesiredModelsType.ExtendedDelivery); } } - return new UsedMappings(ArgMappingsRegister.DeliveryMappings, UsedMappingsType.Delivery); + return new UsedMappings(ArgMappingsRegister.DeliveryMappings, DesiredModelsType.Delivery); } public static bool ContainsValidArgs(string[] args) @@ -65,12 +65,12 @@ public static bool ContainsValidArgs(string[] args) return containsValidArgs; } - public static UsedSdkInfo GetUsedSdkInfo(UsedMappingsType usedMappingsType) => usedMappingsType switch + public static UsedSdkInfo GetUsedSdkInfo(DesiredModelsType desiredModelsType) => desiredModelsType switch { - UsedMappingsType.Delivery => DeliveryProgramOptionsData.UsedSdkInfo, - UsedMappingsType.Management => ManagementProgramOptionsData.UsedSdkInfo, - UsedMappingsType.ExtendedDelivery => ExtendedDeliveryProgramOptionsData.UsedSdkInfo, - _ => throw new ArgumentOutOfRangeException(nameof(usedMappingsType)) + DesiredModelsType.Delivery => DeliveryProgramOptionsData.UsedSdkInfo, + DesiredModelsType.Management => ManagementProgramOptionsData.UsedSdkInfo, + DesiredModelsType.ExtendedDelivery => ExtendedDeliveryProgramOptionsData.UsedSdkInfo, + _ => throw new ArgumentOutOfRangeException(nameof(desiredModelsType)) }; private static bool IsOptionPropertyValid(ProgramOptionsData programOptionsData, string arg) => diff --git a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs index cdd5b7f2..90223871 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs @@ -7,13 +7,13 @@ namespace Kontent.Ai.ModelGenerator.Options; internal class UsedMappings { public IDictionary Mappings { get; } - public UsedMappingsType UsedMappingsType { get; } + public DesiredModelsType DesiredModelsType { get; } - public UsedMappings(IDictionary mappings, UsedMappingsType usedMappingsType) + public UsedMappings(IDictionary mappings, DesiredModelsType desiredModelsType) { Mappings = ArgMappingsRegister.GeneralMappings .Union(mappings) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - UsedMappingsType = usedMappingsType; + DesiredModelsType = desiredModelsType; } } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs b/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs index b433a63e..1d7b5e93 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ValidationExtensions.cs @@ -17,8 +17,8 @@ public static class ValidationExtensions /// CodeGeneratorOptions object to be validated public static void Validate(this CodeGeneratorOptions codeGeneratorOptions) { - var usedMappingsType = codeGeneratorOptions.GetUsedMappingsType(); - if (usedMappingsType == UsedMappingsType.Delivery) + var desiredModelsType = codeGeneratorOptions.GetDesiredModelsType(); + if (desiredModelsType == DesiredModelsType.Delivery) { codeGeneratorOptions.DeliveryOptionsValidate(); } @@ -71,11 +71,11 @@ private static string ExceptionMessage(CodeGeneratorOptions options, string argN string SeePart() { - var paramsLink = options.GetUsedMappingsType() switch + var paramsLink = options.GetDesiredModelsType() switch { - UsedMappingsType.Management => "https://bit.ly/3rSMeDA", - UsedMappingsType.Delivery => "http://bit.ly/k-params", - UsedMappingsType.ExtendedDelivery => "https://bit.ly/3rSMeDA",//todo provide proper link to docs + DesiredModelsType.Management => "https://bit.ly/3rSMeDA", + DesiredModelsType.Delivery => "http://bit.ly/k-params", + DesiredModelsType.ExtendedDelivery => "https://bit.ly/3rSMeDA",//todo provide proper link to docs _ => throw new ArgumentOutOfRangeException() }; diff --git a/src/Kontent.Ai.ModelGenerator/Program.cs b/src/Kontent.Ai.ModelGenerator/Program.cs index 55880e7d..67105e74 100644 --- a/src/Kontent.Ai.ModelGenerator/Program.cs +++ b/src/Kontent.Ai.ModelGenerator/Program.cs @@ -82,7 +82,7 @@ public static async Task Main(string[] args) private static void PrintSdkVersion(UsedMappings usedMappings) { - var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(usedMappings.UsedMappingsType); + var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(usedMappings.DesiredModelsType); Console.WriteLine($"Models were generated for {usedSdkInfo.Name} version {usedSdkInfo.Version}"); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index af176a50..2318376c 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -75,7 +75,7 @@ public void GetSwitchMappings_MissingMapiSwitch_ReturnsDeliveryMappings() }); Assert.Equal(ExpectedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.Delivery, result.UsedMappingsType); + Assert.Equal(DesiredModelsType.Delivery, result.DesiredModelsType); } [Fact] @@ -90,7 +90,7 @@ public void GetSwitchMappings_MapiSwitchIsFalse_ReturnsDeliveryMappings() }); Assert.Equal(ExpectedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.Delivery, result.UsedMappingsType); + Assert.Equal(DesiredModelsType.Delivery, result.DesiredModelsType); } [Fact] @@ -105,7 +105,7 @@ public void GetSwitchMappings_MapiSwitchIsTrue_ReturnsManagementMappings() }); Assert.Equal(ExpectedManagementMappings, result.Mappings); - Assert.Equal(UsedMappingsType.Management, result.UsedMappingsType); + Assert.Equal(DesiredModelsType.Management, result.DesiredModelsType); } [Fact] @@ -120,7 +120,7 @@ public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() }); Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + Assert.Equal(DesiredModelsType.ExtendedDelivery, result.DesiredModelsType); } [Fact] @@ -135,7 +135,7 @@ public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMap }); Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + Assert.Equal(DesiredModelsType.ExtendedDelivery, result.DesiredModelsType); } [Fact] @@ -152,7 +152,7 @@ public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagement }); Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(UsedMappingsType.ExtendedDelivery, result.UsedMappingsType); + Assert.Equal(DesiredModelsType.ExtendedDelivery, result.DesiredModelsType); } [Fact] @@ -267,7 +267,7 @@ public void ContainsContainsValidArgs_UnsupportedExtendedDeliveryOptions_Returns [Fact] public void GetProgramOptionsData_ManagementApi_ReturnsManagementProgramOptionsData() { - var result = ArgHelpers.GetUsedSdkInfo(UsedMappingsType.Management); + var result = ArgHelpers.GetUsedSdkInfo(DesiredModelsType.Management); Assert.Equal("management-sdk-net", result.Name); Assert.Equal(Assembly.GetAssembly(typeof(ManagementOptions)).GetName().Version.ToString(3), result.Version); @@ -276,7 +276,7 @@ public void GetProgramOptionsData_ManagementApi_ReturnsManagementProgramOptionsD [Fact] public void GetProgramOptionsData_DeliveryApi_ReturnsDeliveryProgramOptionsData() { - var result = ArgHelpers.GetUsedSdkInfo(UsedMappingsType.Delivery); + var result = ArgHelpers.GetUsedSdkInfo(DesiredModelsType.Delivery); Assert.Equal("delivery-sdk-net", result.Name); Assert.Equal(Assembly.GetAssembly(typeof(DeliveryOptions)).GetName().Version.ToString(3), result.Version); @@ -285,7 +285,7 @@ public void GetProgramOptionsData_DeliveryApi_ReturnsDeliveryProgramOptionsData( [Fact] public void GetProgramOptionsData_ExtendedDeliveryApi_ReturnsExtendedDeliveryProgramOptionsData() { - var result = ArgHelpers.GetUsedSdkInfo(UsedMappingsType.ExtendedDelivery); + var result = ArgHelpers.GetUsedSdkInfo(DesiredModelsType.ExtendedDelivery); Assert.Equal("delivery-sdk-net", result.Name); Assert.Equal(Assembly.GetAssembly(typeof(DeliveryOptions)).GetName().Version.ToString(3), result.Version); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index 31afa536..0444acc6 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -183,7 +183,7 @@ public void DeliveryApi_ManagementApiIsTrue_ExtendedDeliveryOptionsAreTrue_Retur } [Fact] - public void GetUsedMappingsType_ManagementApi_ReturnsManagement() + public void GetDesiredModelsType_ManagementApi_ReturnsManagement() { var options = new CodeGeneratorOptions { @@ -192,16 +192,16 @@ public void GetUsedMappingsType_ManagementApi_ReturnsManagement() ExtendedDeliverPreviewModels = false }; - var result = options.GetUsedMappingsType(); + var result = options.GetDesiredModelsType(); - Assert.Equal(UsedMappingsType.Management, result); + Assert.Equal(DesiredModelsType.Management, result); } [Theory] [InlineData(true, true)] [InlineData(true, false)] [InlineData(false, true)] - public void GetUsedMappingsType_ExtendedDeliveryModels_ReturnsExtendedDelivery(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + public void GetDesiredModelsType_ExtendedDeliveryModels_ReturnsExtendedDelivery(bool extendedDeliverModels, bool extendedDeliverPreviewModels) { var options = new CodeGeneratorOptions { @@ -210,13 +210,13 @@ public void GetUsedMappingsType_ExtendedDeliveryModels_ReturnsExtendedDelivery(b ExtendedDeliverPreviewModels = extendedDeliverPreviewModels }; - var result = options.GetUsedMappingsType(); + var result = options.GetDesiredModelsType(); - Assert.Equal(UsedMappingsType.ExtendedDelivery, result); + Assert.Equal(DesiredModelsType.ExtendedDelivery, result); } [Fact] - public void GetUsedMappingsType_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsDelivery() + public void GetDesiredModelsType_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsDelivery() { var options = new CodeGeneratorOptions { @@ -225,18 +225,18 @@ public void GetUsedMappingsType_ManagementApiIsFalse_ExtendedDeliveryOptionsAreF ExtendedDeliverPreviewModels = false }; - var result = options.GetUsedMappingsType(); + var result = options.GetDesiredModelsType(); - Assert.Equal(UsedMappingsType.Delivery, result); + Assert.Equal(DesiredModelsType.Delivery, result); } [Fact] - public void GetUsedMappingsType_DefaultOptions_ReturnsDelivery() + public void GetDesiredModelsType_DefaultOptions_ReturnsDelivery() { var options = new CodeGeneratorOptions(); - var result = options.GetUsedMappingsType(); + var result = options.GetDesiredModelsType(); - Assert.Equal(UsedMappingsType.Delivery, result); + Assert.Equal(DesiredModelsType.Delivery, result); } } From 10fbb6066dec8575689f5e31d109e78503d6be46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 15 Sep 2022 16:09:05 +0200 Subject: [PATCH 08/48] 90 refactorings --- .../Options/ArgHelpers.cs | 52 ++++++++++--------- .../Options/UsedMappings.cs | 19 ------- src/Kontent.Ai.ModelGenerator/Program.cs | 10 ++-- .../ArgHelpersTests.cs | 18 +++---- 4 files changed, 38 insertions(+), 61 deletions(-) delete mode 100644 src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index cb06455c..41dfb3e0 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -14,30 +14,9 @@ internal static class ArgHelpers private static readonly ProgramOptionsData DeliveryProgramOptionsData = new ProgramOptionsData(typeof(DeliveryOptions), "delivery-sdk-net"); private static readonly ProgramOptionsData ExtendedDeliveryProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), typeof(DeliveryOptions), "delivery-sdk-net"); - public static UsedMappings GetSwitchMappings(string[] args) - { - var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); - var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); - var extendedDeliverPreviewDecidingArgs = new DecidingArgs("-r", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels))); - - for (var i = 0; i < args.Length; i++) - { - if (i + 1 >= args.Length || args[i + 1] != "true") continue; - - if (args[i] == managementDecidingArgs.ShorthandedArgName || args[i] == managementDecidingArgs.FullArgName) - { - return new UsedMappings(ArgMappingsRegister.ManagementMappings, DesiredModelsType.Management); - } - - if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || - args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) - { - return new UsedMappings(ArgMappingsRegister.ExtendedDeliveryMappings, DesiredModelsType.ExtendedDelivery); - } - } - - return new UsedMappings(ArgMappingsRegister.DeliveryMappings, DesiredModelsType.Delivery); - } + public static IDictionary GetSwitchMappings(string[] args) => ArgMappingsRegister.GeneralMappings + .Union(GetSpecificSwitchMappings(args)) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); public static bool ContainsValidArgs(string[] args) { @@ -73,6 +52,31 @@ public static bool ContainsValidArgs(string[] args) _ => throw new ArgumentOutOfRangeException(nameof(desiredModelsType)) }; + private static IDictionary GetSpecificSwitchMappings(string[] args) + { + var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); + var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); + var extendedDeliverPreviewDecidingArgs = new DecidingArgs("-r", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels))); + + for (var i = 0; i < args.Length; i++) + { + if (i + 1 >= args.Length || args[i + 1] != "true") continue; + + if (args[i] == managementDecidingArgs.ShorthandedArgName || args[i] == managementDecidingArgs.FullArgName) + { + return ArgMappingsRegister.ManagementMappings; + } + + if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || + args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) + { + return ArgMappingsRegister.ExtendedDeliveryMappings; + } + } + + return ArgMappingsRegister.DeliveryMappings; + } + private static bool IsOptionPropertyValid(ProgramOptionsData programOptionsData, string arg) => IsOptionPropertyValid(programOptionsData.OptionProperties.Select(prop => $"{programOptionsData.OptionsName}:{prop.Name}"), arg); diff --git a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs b/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs deleted file mode 100644 index 90223871..00000000 --- a/src/Kontent.Ai.ModelGenerator/Options/UsedMappings.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Kontent.Ai.ModelGenerator.Core.Configuration; - -namespace Kontent.Ai.ModelGenerator.Options; - -internal class UsedMappings -{ - public IDictionary Mappings { get; } - public DesiredModelsType DesiredModelsType { get; } - - public UsedMappings(IDictionary mappings, DesiredModelsType desiredModelsType) - { - Mappings = ArgMappingsRegister.GeneralMappings - .Union(mappings) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - DesiredModelsType = desiredModelsType; - } -} diff --git a/src/Kontent.Ai.ModelGenerator/Program.cs b/src/Kontent.Ai.ModelGenerator/Program.cs index 67105e74..a1be90d0 100644 --- a/src/Kontent.Ai.ModelGenerator/Program.cs +++ b/src/Kontent.Ai.ModelGenerator/Program.cs @@ -27,13 +27,11 @@ public static async Task Main(string[] args) return 1; } - var usedMappings = ArgHelpers.GetSwitchMappings(args); - // Build a configuration object from given sources var configuration = new ConfigurationBuilder() .SetBasePath(Environment.CurrentDirectory) .AddJsonFile("appSettings.json", true) - .AddCommandLine(args, usedMappings.Mappings) + .AddCommandLine(args, ArgHelpers.GetSwitchMappings(args)) .Build(); // Fill the DI container @@ -52,7 +50,7 @@ public static async Task Main(string[] args) var options = serviceProvider.GetService>().Value; options.Validate(); - PrintSdkVersion(usedMappings); + PrintSdkVersion(options); // Code generator entry point if (options.ManagementApi()) @@ -80,9 +78,9 @@ public static async Task Main(string[] args) private static async Task WriteErrorMessageAsync(string message) => await Console.Error.WriteLineAsync(message); - private static void PrintSdkVersion(UsedMappings usedMappings) + private static void PrintSdkVersion(CodeGeneratorOptions codeGeneratorOptions) { - var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(usedMappings.DesiredModelsType); + var usedSdkInfo = ArgHelpers.GetUsedSdkInfo(codeGeneratorOptions.GetDesiredModelsType()); Console.WriteLine($"Models were generated for {usedSdkInfo.Name} version {usedSdkInfo.Version}"); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index 2318376c..80f38175 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -74,8 +74,7 @@ public void GetSwitchMappings_MissingMapiSwitch_ReturnsDeliveryMappings() Guid.NewGuid().ToString() }); - Assert.Equal(ExpectedDeliveryMappings, result.Mappings); - Assert.Equal(DesiredModelsType.Delivery, result.DesiredModelsType); + Assert.Equal(ExpectedDeliveryMappings, result); } [Fact] @@ -89,8 +88,7 @@ public void GetSwitchMappings_MapiSwitchIsFalse_ReturnsDeliveryMappings() "false" }); - Assert.Equal(ExpectedDeliveryMappings, result.Mappings); - Assert.Equal(DesiredModelsType.Delivery, result.DesiredModelsType); + Assert.Equal(ExpectedDeliveryMappings, result); } [Fact] @@ -104,8 +102,7 @@ public void GetSwitchMappings_MapiSwitchIsTrue_ReturnsManagementMappings() "true" }); - Assert.Equal(ExpectedManagementMappings, result.Mappings); - Assert.Equal(DesiredModelsType.Management, result.DesiredModelsType); + Assert.Equal(ExpectedManagementMappings, result); } [Fact] @@ -119,8 +116,7 @@ public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() "true" }); - Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(DesiredModelsType.ExtendedDelivery, result.DesiredModelsType); + Assert.Equal(ExpectedExtendedDeliveryMappings, result); } [Fact] @@ -134,8 +130,7 @@ public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMap "true" }); - Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(DesiredModelsType.ExtendedDelivery, result.DesiredModelsType); + Assert.Equal(ExpectedExtendedDeliveryMappings, result); } [Fact] @@ -151,8 +146,7 @@ public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagement "true" }); - Assert.Equal(ExpectedExtendedDeliveryMappings, result.Mappings); - Assert.Equal(DesiredModelsType.ExtendedDelivery, result.DesiredModelsType); + Assert.Equal(ExpectedExtendedDeliveryMappings, result); } [Fact] From 2410e06ecc80cb6061c74ee69bc49c2c996d289e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 15 Sep 2022 16:36:26 +0200 Subject: [PATCH 09/48] 90 introduce ExtendedDeliveryCodeGenerator --- .../DeliveryCodeGenerator.cs | 14 +--------- .../DeliveryCodeGeneratorBase.cs | 18 ++++++++++++ .../ExtendedDeliveryCodeGenerator.cs | 28 +++++++++++++++++++ src/Kontent.Ai.ModelGenerator/Program.cs | 12 ++++---- 4 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs create mode 100644 src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs index f06ca5fa..b23412df 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs @@ -12,7 +12,7 @@ namespace Kontent.Ai.ModelGenerator.Core; -public class DeliveryCodeGenerator : CodeGeneratorBase +public class DeliveryCodeGenerator : DeliveryCodeGeneratorBase { private readonly IDeliveryClient _deliveryClient; @@ -27,18 +27,6 @@ public DeliveryCodeGenerator(IOptions options, IOutputProv _deliveryClient = deliveryClient; } - public new async Task RunAsync() - { - await base.RunAsync(); - - if (Options.WithTypeProvider) - { - await GenerateTypeProvider(); - } - - return 0; - } - protected override async Task> GetClassCodeGenerators() { var deliveryTypes = (await _deliveryClient.GetTypesAsync()).Types; diff --git a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs new file mode 100644 index 00000000..c12e6b48 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs @@ -0,0 +1,18 @@ +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Microsoft.Extensions.Options; +using System; +using System.Threading.Tasks; + +namespace Kontent.Ai.ModelGenerator.Core; + +public abstract class DeliveryCodeGeneratorBase : CodeGeneratorBase +{ + protected DeliveryCodeGeneratorBase(IOptions options, IOutputProvider outputProvider) : base(options, outputProvider) + { + } + + public new async Task RunAsync() + { + throw new NotImplementedException(); + } +} diff --git a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs new file mode 100644 index 00000000..b8c8eeec --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Kontent.Ai.Management; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.TypeSnippets; +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Microsoft.Extensions.Options; + +namespace Kontent.Ai.ModelGenerator.Core; + +public class ExtendedDeliveryCodeGenerator : DeliveryCodeGeneratorBase +{ + public ExtendedDeliveryCodeGenerator(IOptions options, IOutputProvider outputProvider, IManagementClient managementClient) : base(options, outputProvider) + { + } + + protected override Task> GetClassCodeGenerators() + { + throw new NotImplementedException(); + } + + internal IEnumerable GetClassCodeGenerator(ContentTypeModel contentType, List managementSnippets, List contentTypes) + { + throw new NotImplementedException(); + } +} diff --git a/src/Kontent.Ai.ModelGenerator/Program.cs b/src/Kontent.Ai.ModelGenerator/Program.cs index a1be90d0..711cbb25 100644 --- a/src/Kontent.Ai.ModelGenerator/Program.cs +++ b/src/Kontent.Ai.ModelGenerator/Program.cs @@ -42,6 +42,7 @@ public static async Task Main(string[] args) services.AddTransient(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); // Build the DI container var serviceProvider = services.BuildServiceProvider(); @@ -53,12 +54,13 @@ public static async Task Main(string[] args) PrintSdkVersion(options); // Code generator entry point - if (options.ManagementApi()) + return options.GetDesiredModelsType() switch { - return await serviceProvider.GetService().RunAsync(); - } - - return await serviceProvider.GetService().RunAsync(); + DesiredModelsType.Delivery => await serviceProvider.GetService().RunAsync(), + DesiredModelsType.ExtendedDelivery => await serviceProvider.GetService().RunAsync(), + DesiredModelsType.Management => await serviceProvider.GetService().RunAsync(), + _ => throw new ArgumentOutOfRangeException() + }; } catch (AggregateException aex) { From c3d3faad61c614fd7393b160652be350182470fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 16 Sep 2022 15:51:24 +0200 Subject: [PATCH 10/48] 90 use options instead strings in BaseClassCodeGenerator --- .../CodeGeneratorBase.cs | 2 +- .../Class/BaseClassCodeGenerator.cs | 17 ++++++++-------- .../Class/BaseClassCodeGeneratorTests.cs | 20 +++++++++++++------ 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs index 68b93a43..fe23fb77 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs @@ -125,7 +125,7 @@ private async Task GenerateBaseClass() return; } - var baseClassCodeGenerator = new BaseClassCodeGenerator(Options.BaseClass, Options.Namespace); + var baseClassCodeGenerator = new BaseClassCodeGenerator(Options); foreach (var codeGenerator in classCodeGenerators) { diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs index 0342aa88..24a4050a 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/BaseClassCodeGenerator.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Helpers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -16,16 +17,16 @@ public class BaseClassCodeGenerator : GeneralGenerator /// private readonly ICollection _classesToExtend = new HashSet(); - private readonly string _className; + private readonly CodeGeneratorOptions _options; /// /// The calculated Extender Classname /// - public string ExtenderClassName => $"{_className}Extender"; + public string ExtenderClassName => $"{_options.BaseClass}Extender"; - public BaseClassCodeGenerator(string className, string @namespace = ClassCodeGenerator.DefaultNamespace) : base(@namespace) + public BaseClassCodeGenerator(CodeGeneratorOptions options) : base(options.Namespace) { - _className = className; + _options = options; } /// @@ -54,7 +55,7 @@ public string GenerateBaseClassCode() namespace {Namespace} {{ - public partial class {_className} + public partial class {_options.BaseClass} {{ // This class can be used to extend the generated classes. They inherit from this type in {ExtenderClassName}.cs. }} @@ -73,7 +74,7 @@ public partial class {_className} public string GenerateExtenderCode() { var extenders = _classesToExtend.OrderBy(c => c) - .Select((c) => $"public partial class {c} : {_className} {{ }}") + .Select((c) => $"public partial class {c} : {_options.BaseClass} {{ }}") .Aggregate((p, n) => p + Environment.NewLine + n); var tree = CSharpSyntaxTree.ParseText( @@ -82,7 +83,7 @@ public string GenerateExtenderCode() namespace {Namespace} {{ - // These classes extend the generated models to all inherit from the common basetype {_className}. + // These classes extend the generated models to all inherit from the common basetype {_options.BaseClass}. {extenders} }}"); @@ -99,5 +100,5 @@ protected override SyntaxTrivia ClassDescription() => private SyntaxTrivia ExtenderClassDescription => ClassDeclarationHelper.GenerateSyntaxTrivia( @$"{LostChangesComment} -// For further modifications of the class, create or modify the '{_className}.cs' file with the partial class."); +// For further modifications of the class, create or modify the '{_options.BaseClass}.cs' file with the partial class."); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs index bd2e3bfb..00bd170f 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Xunit; @@ -7,12 +8,15 @@ namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; public class BaseClassCodeGeneratorTests { - private const string BaseClassName = "ContentBase"; + private readonly CodeGeneratorOptions CodeGeneratorOptions = new CodeGeneratorOptions + { + BaseClass = "ContentBase" + }; [Fact] public void GenerateBaseClassCodeWithDefaultNamespace() { - var codeGenerator = new BaseClassCodeGenerator(BaseClassName); + var codeGenerator = new BaseClassCodeGenerator(CodeGeneratorOptions); var executingPath = AppContext.BaseDirectory; var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); @@ -25,12 +29,16 @@ public void GenerateBaseClassCodeWithDefaultNamespace() [Fact] public void GenerateBaseClassCodeWithCustomNamespace() { - var customNamespace = "CustomNamespace"; - var codeGenerator = new BaseClassCodeGenerator(BaseClassName, customNamespace); + var codeGenerationOptions = new CodeGeneratorOptions + { + BaseClass = CodeGeneratorOptions.BaseClass, + Namespace = "CustomNamespace" + }; + var codeGenerator = new BaseClassCodeGenerator(codeGenerationOptions); var executingPath = AppContext.BaseDirectory; var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); - expectedBaseClassCode = expectedBaseClassCode.Replace(ClassCodeGenerator.DefaultNamespace, customNamespace); + expectedBaseClassCode = expectedBaseClassCode.Replace(ClassCodeGenerator.DefaultNamespace, CodeGeneratorOptions.Namespace); var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); @@ -40,7 +48,7 @@ public void GenerateBaseClassCodeWithCustomNamespace() [Fact] public void GenerateExtenderClassCode() { - var codeGenerator = new BaseClassCodeGenerator(BaseClassName); + var codeGenerator = new BaseClassCodeGenerator(CodeGeneratorOptions); codeGenerator.AddClassNameToExtend("Article"); codeGenerator.AddClassNameToExtend("Office"); From a9903daab80d10baa10eae0aad0ad9e6980b9937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 16 Sep 2022 16:03:23 +0200 Subject: [PATCH 11/48] 90 introduce class code generators --- .../Class/ContentItemClassCodeGenerator.cs | 25 +++++++++++++++++++ .../ExtendedDeliveryClassCodeGenerator.cs | 16 ++++++++++++ ...TypedExtendedDeliveryClassCodeGenerator.cs | 18 +++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs create mode 100644 src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs create mode 100644 src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs new file mode 100644 index 00000000..68fc1987 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs @@ -0,0 +1,25 @@ +using System; +using Kontent.Ai.ModelGenerator.Core.Common; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class ContentItemClassCodeGenerator : ClassCodeGenerator +{ + public const string DefaultContentItemClassName = "IContentItem"; + + public ContentItemClassCodeGenerator(string @namespace = DefaultNamespace) + : this(new ClassDefinition(DefaultContentItemClassName), DefaultContentItemClassName, @namespace) + { + } + + private ContentItemClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) + { + } + + protected override UsingDirectiveSyntax[] GetApiUsings() + { + throw new NotImplementedException(); + } +} diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs new file mode 100644 index 00000000..53341c77 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Kontent.Ai.ModelGenerator.Core.Common; + +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class ExtendedDeliveryClassCodeGenerator : DeliveryClassCodeGenerator +{ + public ExtendedDeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) + { + } +} diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs new file mode 100644 index 00000000..30aa2ebb --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs @@ -0,0 +1,18 @@ +using System; +using Kontent.Ai.ModelGenerator.Core.Common; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; + +public class TypedExtendedDeliveryClassCodeGenerator : ClassCodeGenerator +{ + public TypedExtendedDeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + : base(classDefinition, classFilename, @namespace) + { + } + + protected override UsingDirectiveSyntax[] GetApiUsings() + { + throw new NotImplementedException(); + } +} From a5f5905c0499cef5bb338af3681ab10c33970608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 16 Sep 2022 17:28:08 +0200 Subject: [PATCH 12/48] 90 change GetClassDeclaration return type to TypeDeclarationSyntax --- .../Generators/Class/ClassCodeGenerator.cs | 14 ++++++++++++-- .../Generators/Class/DeliveryClassCodeGenerator.cs | 2 +- .../Class/ManagementClassCodeGenerator.cs | 2 +- .../Generators/Class/PartialClassCodeGenerator.cs | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs index d60309f1..e770e446 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ClassCodeGenerator.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Helpers; using Microsoft.CodeAnalysis; @@ -37,7 +38,16 @@ public string GenerateCode() protected abstract UsingDirectiveSyntax[] GetApiUsings(); - protected virtual ClassDeclarationSyntax GetClassDeclaration() => SyntaxFactory.ClassDeclaration(ClassDefinition.ClassName) + protected virtual MemberDeclarationSyntax[] Properties + => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => SyntaxFactory + .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .AddAccessorListAccessors( + GetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration), + GetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration) + )).ToArray(); + + protected virtual TypeDeclarationSyntax GetClassDeclaration() => SyntaxFactory.ClassDeclaration(ClassDefinition.ClassName) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword)); @@ -48,7 +58,7 @@ protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.Gen protected static AccessorDeclarationSyntax GetAccessorDeclaration(SyntaxKind kind) => SyntaxFactory.AccessorDeclaration(kind).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); - private CompilationUnitSyntax GetCompilationUnit(ClassDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usings) + private CompilationUnitSyntax GetCompilationUnit(TypeDeclarationSyntax classDeclaration, UsingDirectiveSyntax[] usings) { var compilationUnit = SyntaxFactory.CompilationUnit() .AddUsings(usings) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs index d269b9e8..c56acfe9 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGenerator.cs @@ -11,7 +11,7 @@ public DeliveryClassCodeGenerator(ClassDefinition classDefinition, string classF { } - protected override ClassDeclarationSyntax GetClassDeclaration() + protected override TypeDeclarationSyntax GetClassDeclaration() { var classDeclaration = base.GetClassDeclaration(); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs index 1ae34545..cebfd038 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs @@ -29,7 +29,7 @@ protected override UsingDirectiveSyntax[] GetApiUsings() => SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName($"{nameof(Newtonsoft)}.{nameof(Newtonsoft.Json)}")) }; - protected override ClassDeclarationSyntax GetClassDeclaration() + protected override TypeDeclarationSyntax GetClassDeclaration() { var classDeclaration = base.GetClassDeclaration(); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs index 972d6967..d66c7712 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/PartialClassCodeGenerator.cs @@ -13,7 +13,7 @@ public PartialClassCodeGenerator(ClassDefinition classDefinition, string classFi { } - protected override ClassDeclarationSyntax GetClassDeclaration() + protected override TypeDeclarationSyntax GetClassDeclaration() { var classDeclaration = base.GetClassDeclaration(); From b6ec2c790e017e6e7d2e9fb946c6e8986e9414f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 22 Sep 2022 11:30:48 +0200 Subject: [PATCH 13/48] 90 impl + test of classcode generators --- .../Common/ClassDefinition.cs | 13 ++ .../Common/Property.cs | 46 ++++++ .../DeliveryCodeGeneratorBase.cs | 34 +++- .../Class/ContentItemClassCodeGenerator.cs | 26 ++- .../Class/DeliveryClassCodeGeneratorBase.cs | 9 - .../ExtendedDeliveryClassCodeGenerator.cs | 21 ++- ...TypedExtendedDeliveryClassCodeGenerator.cs | 5 + ...pe_CompiledCode_ExtendedDeliveryModels.txt | 35 ++++ .../Assets/IContentItem_CompiledCode.txt | 18 ++ .../CodeGeneratorTestsBase.cs | 33 +++- .../Class/BaseClassCodeGeneratorTests.cs | 2 +- .../Class/ClassCodeGeneratorTestsBase.cs | 34 ++++ .../ContentItemClassCodeGeneratorTests.cs | 53 ++++++ ...ExtendedDeliveryClassCodeGeneratorTests.cs | 156 ++++++++++++++++++ 14 files changed, 463 insertions(+), 22 deletions(-) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs index 193c9823..75af8d7c 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassDefinition.cs @@ -47,6 +47,19 @@ public void AddSystemProperty() AddProperty(new Property("system", nameof(IContentItemSystemAttributes))); } + public void TryAddSystemProperty() + { + try + { + AddProperty(new Property("system", nameof(IContentItemSystemAttributes))); + } + catch (InvalidOperationException) + { + Console.WriteLine( + $"Warning: Can't add 'System' property. It's in collision with existing element in Content Type '{ClassName}'."); + } + } + private bool PropertyIsAlreadyPresent(Property property) { return Properties.Exists(e => e.Identifier == property.Identifier); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index f0ca21df..20977205 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -39,6 +39,21 @@ public class Property { "custom", "string" } }; + internal static readonly Dictionary ExtendedDeliverElementTypesDictionary = new Dictionary + { + { ElementMetadataType.Text.ToString(), "string" }, + { ElementMetadataType.RichText.ToString(), "string" }, + { ElementMetadataType.RichText + StructuredSuffix, nameof(IRichTextContent)}, + { ElementMetadataType.Number.ToString(), "decimal?" }, + { ElementMetadataType.MultipleChoice.ToString(), $"{nameof(IEnumerable)}<{nameof(IMultipleChoiceOption)}>"}, + { ElementMetadataType.DateTime.ToString(), "DateTime?" }, + { ElementMetadataType.Asset.ToString(), $"{nameof(IEnumerable)}<{nameof(IAsset)}>" }, + { ElementMetadataType.LinkedItems.ToString(), null }, + { ElementMetadataType.Taxonomy.ToString(), $"{nameof(IEnumerable)}<{nameof(ITaxonomyTerm)}>" }, + { ElementMetadataType.UrlSlug.ToString(), "string" }, + { ElementMetadataType.Custom.ToString(), "string" } + }; + private static readonly Dictionary ManagementElementTypesDictionary = new Dictionary { { ElementMetadataType.Text, nameof(TextElement) }, @@ -61,6 +76,13 @@ public Property(string codename, string typeName, string id = null) Id = id; } + public static bool IsContentTypeSupported(string elementType, bool extendedDeliverModels) + { + return extendedDeliverModels + ? ExtendedDeliverElementTypesDictionary.ContainsKey(elementType) + : DeliverElementTypesDictionary.ContainsKey(elementType); + } + public static bool IsContentTypeSupported(string elementType) { return DeliverElementTypesDictionary.ContainsKey(elementType); @@ -95,4 +117,28 @@ public static Property FromContentTypeElement(ElementMetadataBase element) throw new ArgumentException($"Unknown Content Type {element.Type}", nameof(element)); } + + public static Property FromContentTypeElement(ElementMetadataBase element, string elementType) + { + return FromContentTypeElement(element, elementType, element.Codename); + } + + public static Property FromContentTypeElement(ElementMetadataBase element, string elementType, string finalPropertyName) + { + if (IsContentTypeSupported(element.Type.ToString(), true)) + { + var resultElementType = element.Type == ElementMetadataType.LinkedItems + ? elementType + : ExtendedDeliverElementTypesDictionary[elementType]; + + return new Property(finalPropertyName, resultElementType); + } + + if (element.Type == ElementMetadataType.Guidelines) + { + throw new UnsupportedTypeException(); + } + + throw new ArgumentException($"Unknown Content Type {element.Type}", nameof(element)); + } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs index c12e6b48..679fc311 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs @@ -1,6 +1,9 @@ using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Kontent.Ai.ModelGenerator.Core.Generators; using Microsoft.Extensions.Options; using System; +using System.Linq; using System.Threading.Tasks; namespace Kontent.Ai.ModelGenerator.Core; @@ -13,6 +16,35 @@ protected DeliveryCodeGeneratorBase(IOptions options, IOut public new async Task RunAsync() { - throw new NotImplementedException(); + await base.RunAsync(); + + if (Options.WithTypeProvider) + { + await GenerateTypeProvider(); + } + + return 0; + } + + private async Task GenerateTypeProvider() + { + var classCodeGenerators = await GetClassCodeGenerators(); + + if (!classCodeGenerators.Any()) + { + Console.WriteLine(NoContentTypeAvailableMessage); + return; + } + + var typeProviderCodeGenerator = new TypeProviderCodeGenerator(Options.Namespace); + + foreach (var codeGenerator in classCodeGenerators) + { + var className = codeGenerator is ContentItemClassCodeGenerator ? codeGenerator.ClassDefinition.Codename : codeGenerator.ClassDefinition.ClassName; + typeProviderCodeGenerator.AddContentType(codeGenerator.ClassDefinition.Codename, className); + } + + var typeProviderCode = typeProviderCodeGenerator.GenerateCode(); + WriteToOutputProvider(typeProviderCode, TypeProviderCodeGenerator.ClassName, true); } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs index 68fc1987..ffe43507 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs @@ -1,5 +1,7 @@ -using System; -using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Helpers; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; @@ -18,8 +20,24 @@ private ContentItemClassCodeGenerator(ClassDefinition classDefinition, string cl { } - protected override UsingDirectiveSyntax[] GetApiUsings() + protected override UsingDirectiveSyntax[] GetApiUsings() => new UsingDirectiveSyntax[] { - throw new NotImplementedException(); + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Delivery.Abstractions.IApiResponse).Namespace!)) + }; + + protected override TypeDeclarationSyntax GetClassDeclaration() + { + ClassDefinition.TryAddSystemProperty(); + + var classDeclaration = SyntaxFactory.InterfaceDeclaration(ClassDefinition.Codename) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .AddMembers(Properties); + + return classDeclaration; } + + protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.GenerateSyntaxTrivia( + @$"{LostChangesComment} +// Class is meant to represent common IContentItem interface, thus is not suitable for further modifications. +// If you require to extend all of your generated models you can use base classes see https://bit.ly/3yugE2z."); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs index 3e20c166..74cab2ce 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/DeliveryClassCodeGeneratorBase.cs @@ -13,15 +13,6 @@ protected DeliveryClassCodeGeneratorBase(ClassDefinition classDefinition, string { } - protected MemberDeclarationSyntax[] Properties - => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => SyntaxFactory - .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) - .AddAccessorListAccessors( - GetAccessorDeclaration(SyntaxKind.GetAccessorDeclaration), - GetAccessorDeclaration(SyntaxKind.SetAccessorDeclaration) - )).ToArray(); - protected MemberDeclarationSyntax[] PropertyCodenameConstants => ClassDefinition.PropertyCodenameConstants .OrderBy(p => p) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs index 53341c77..6907ad98 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Common; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; @@ -13,4 +10,16 @@ public ExtendedDeliveryClassCodeGenerator(ClassDefinition classDefinition, strin : base(classDefinition, classFilename, @namespace) { } + + protected override TypeDeclarationSyntax GetClassDeclaration() + { + ClassDefinition.TryAddSystemProperty(); + + var classDeclaration = base.GetClassDeclaration(); + + var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(ContentItemClassCodeGenerator.DefaultContentItemClassName)); + classDeclaration = (TypeDeclarationSyntax)classDeclaration.AddBaseListTypes(baseType); + + return classDeclaration; + } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs index 30aa2ebb..2ce1e57f 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs @@ -15,4 +15,9 @@ protected override UsingDirectiveSyntax[] GetApiUsings() { throw new NotImplementedException(); } + + protected override TypeDeclarationSyntax GetClassDeclaration() + { + throw new NotImplementedException(); + } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt new file mode 100644 index 00000000..72371d33 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt @@ -0,0 +1,35 @@ +// +// This code was generated by a kontent-generators-net tool +// (see https://github.com/kontent-ai/model-generator-net). +// +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// For further modifications of the class, create a separate file with the partial class. +// + +using System; +using System.Collections.Generic; +using Kontent.Ai.Delivery.Abstractions; + +namespace KontentAiModels +{ + public partial class CompleteContentType : IContentItem + { + public const string Codename = "Complete content type"; + + public IEnumerable Asset { get; set; } + public string Custom { get; set; } + public DateTime? DateTime { get; set; } + public IEnumerable ModularContentArticle { get; set; } + public IEnumerable ModularContentBlog { get; set; } + public IEnumerable ModularContentCoffees { get; set; } + public IEnumerable ModularContentHeroes { get; set; } + public IEnumerable MultipleChoice { get; set; } + public decimal? Number { get; set; } + public string RichText { get; set; } + public IRichTextContent RichTextStructured { get; set; } + public IContentItemSystemAttributes System { get; set; } + public IEnumerable Taxonomy { get; set; } + public string Text { get; set; } + public string UrlSlug { get; set; } + } +} \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt new file mode 100644 index 00000000..62b288b3 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt @@ -0,0 +1,18 @@ +// +// This code was generated by a kontent-generators-net tool +// (see https://github.com/kontent-ai/model-generator-net). +// +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// Class is meant to represent common IContentItem interface, thus is not suitable for further modifications. +// If you require to extend all of your generated models you can use base classes see https://bit.ly/3yugE2z. +// + +using Kontent.Ai.Delivery.Abstractions; + +namespace KontentAiModels +{ + public interface IContentItem + { + public IContentItemSystemAttributes System { get; set; } + } +} \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs b/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs index 2e03c030..d64016b1 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs @@ -1,4 +1,12 @@ -using System.IO; +using Kontent.Ai.Management.Models.Shared; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.TypeSnippets; +using Kontent.Ai.Management; +using Kontent.Ai.ModelGenerator.Tests.Fixtures; +using Moq; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; namespace Kontent.Ai.ModelGenerator.Tests; @@ -16,4 +24,27 @@ protected CodeGeneratorTestsBase() } Directory.CreateDirectory(TempDir); } + + protected static IManagementClient CreateManagementClient() + { + var managementModelsProvider = new ManagementModelsProvider(); + var managementClientMock = new Mock(); + + var contentTypeListingResponseModel = new Mock>(); + contentTypeListingResponseModel.As>() + .Setup(c => c.GetEnumerator()) + .Returns(() => managementModelsProvider.ManagementContentTypeModels); + + var contentTypeSnippetListingResponseModel = new Mock>(); + contentTypeSnippetListingResponseModel.As>() + .Setup(c => c.GetEnumerator()) + .Returns(() => managementModelsProvider.ManagementContentTypeSnippetModels); + + managementClientMock.Setup(client => client.ListContentTypeSnippetsAsync()) + .Returns(Task.FromResult(contentTypeSnippetListingResponseModel.Object)); + managementClientMock.Setup(client => client.ListContentTypesAsync()) + .Returns(Task.FromResult(contentTypeListingResponseModel.Object)); + + return managementClientMock.Object; + } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs index 00bd170f..b275a380 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs @@ -38,7 +38,7 @@ public void GenerateBaseClassCodeWithCustomNamespace() var executingPath = AppContext.BaseDirectory; var expectedBaseClassCode = File.ReadAllText(executingPath + "/Assets/BaseClass_CompiledCode.txt"); - expectedBaseClassCode = expectedBaseClassCode.Replace(ClassCodeGenerator.DefaultNamespace, CodeGeneratorOptions.Namespace); + expectedBaseClassCode = expectedBaseClassCode.Replace(ClassCodeGenerator.DefaultNamespace, codeGenerationOptions.Namespace); var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs new file mode 100644 index 00000000..ea34b1cc --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs @@ -0,0 +1,34 @@ +using Kontent.Ai.ModelGenerator.Core.Common; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis; +using System.IO; +using System.Linq; +using Xunit; + +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public abstract class ClassCodeGeneratorTestsBase +{ + protected readonly ClassDefinition ClassDefinition = new ClassDefinition("Complete content type"); + + protected void AssertCompiledCode(CSharpCompilation compilation) + { + using var ms = new MemoryStream(); + var result = compilation.Emit(ms); + var compilationErrors = "Compilation errors:\n"; + + if (!result.Success) + { + var failures = result.Diagnostics.Where(diagnostic => + diagnostic.IsWarningAsError || + diagnostic.Severity == DiagnosticSeverity.Error); + + foreach (var diagnostic in failures) + { + compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; + } + } + + Assert.True(result.Success, compilationErrors); + } +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs new file mode 100644 index 00000000..0d7e9fd6 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs @@ -0,0 +1,53 @@ +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using System; +using System.IO; +using System.Reflection; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; + +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class ContentItemClassCodeGeneratorTests : ClassCodeGeneratorTestsBase +{ + [Fact] + public void Constructor_CreatesInstance() + { + var classCodeGenerator = new ContentItemClassCodeGenerator(); + + Assert.NotNull(classCodeGenerator); + Assert.True(classCodeGenerator.OverwriteExisting); + } + + [Fact] + public void Build_CreatesClassWithSystemProperty() + { + var classCodeGenerator = new ContentItemClassCodeGenerator(); + + var compiledCode = classCodeGenerator.GenerateCode(); + + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/IContentItem_CompiledCode.txt"); + + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + } + + [Fact] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + { + var classCodeGenerator = new ContentItemClassCodeGenerator(); + + var compiledCode = classCodeGenerator.GenerateCode(); + + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, + references: new[] { + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + AssertCompiledCode(compilation); + } +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs new file mode 100644 index 00000000..6a34bb26 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Kontent.Ai.Management.Models.Shared; +using Kontent.Ai.Management.Models.Types.Elements; +using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis; +using Xunit; +using Kontent.Ai.Management.Models.Types; + +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class ExtendedDeliveryClassCodeGeneratorTests : ClassCodeGeneratorTestsBase +{ + public ExtendedDeliveryClassCodeGeneratorTests() + { + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"), + ElementMetadataType.Text.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText), + ElementMetadataType.RichText.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number), + ElementMetadataType.Number.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice), + ElementMetadataType.MultipleChoice.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime), + ElementMetadataType.DateTime.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset), + ElementMetadataType.Asset.ToString())); + + // Linked items elements are limited to a single type with at least 1 item. + var singleAllowedTypeMultiItemsTypeName = "Hero"; + var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestHelper. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); + singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); + singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + // Linked items element limited to a single type with at most or exactly 1 item. + var singleAllowedTypeExactlySingleItemTypeName = "Article"; + var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestHelper. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); + singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); + singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. + var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestHelper. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "modular_content_blog", ElementMetadataType.LinkedItems); + multiAllowedTypesSingleItem.AllowedTypes = new List(new List + { + Reference.ByCodename("Hero"), + Reference.ByCodename("Article") + }); + multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesSingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + // Linked items element limited to multiple types with at least 1 item. + var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestHelper. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); + multiAllowedTypesMultiItems.AllowedTypes = new List(new List + { + Reference.ByCodename("Hero"), + Reference.ByCodename("Article") + }); + multiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), + ElementMetadataType.RichText + Property.StructuredSuffix)); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy), + ElementMetadataType.Taxonomy.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug), + ElementMetadataType.UrlSlug.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom), + ElementMetadataType.Custom.ToString())); + } + + [Fact] + public void Constructor_CreatesInstance() + { + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + + Assert.NotNull(classCodeGenerator); + Assert.True(classCodeGenerator.OverwriteExisting); + } + + [Fact] + public void Build_CreatesClassWithCompleteContentType() + { + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + + var compiledCode = classCodeGenerator.GenerateCode(); + + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt"); + + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + } + + [Fact] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + { + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + var compiledCode = classCodeGenerator.GenerateCode(); + + var heroClassDefinition = new ClassDefinition("Hero"); + var heroClassCodeGenerator = new ExtendedDeliveryClassCodeGenerator(heroClassDefinition, heroClassDefinition.ClassName); + var compiledHeroCode = heroClassCodeGenerator.GenerateCode(); + + var articleClassDefinition = new ClassDefinition("Article"); + var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); + var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); + + var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); + var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); + + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] + { + CSharpSyntaxTree.ParseText(compiledContentItemCode), + CSharpSyntaxTree.ParseText(compiledHeroCode), + CSharpSyntaxTree.ParseText(compiledArticleCode), + CSharpSyntaxTree.ParseText(compiledCode), + }, + references: new[] { + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq")).Location), + MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + AssertCompiledCode(compilation); + } +} From 422268e6d236cff4b4abb37daf074216512856ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 22 Sep 2022 11:38:52 +0200 Subject: [PATCH 14/48] 90 refactoring management and delivery class code generator tests --- .../Class/DeliveryClassCodeGeneratorTests.cs | 73 +++++--------- .../ManagementClassCodeGeneratorTests.cs | 95 ++++++------------- 2 files changed, 50 insertions(+), 118 deletions(-) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs index 2637cbca..e088a596 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Linq; using System.Reflection; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Generators.Class; @@ -10,14 +9,29 @@ namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; -public class DeliveryClassCodeGeneratorTests +public class DeliveryClassCodeGeneratorTests : ClassCodeGeneratorTestsBase { + public DeliveryClassCodeGeneratorTests() + { + ClassDefinition.AddProperty(Property.FromContentTypeElement("text", "text")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("number", "number")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("asset", "asset")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("url_slug", "url_slug")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("custom", "custom")); + + ClassDefinition.TryAddSystemProperty(); + } + [Fact] public void Constructor_CreatesInstance() { - var classDefinition = new ClassDefinition("Complete content type"); - - var classCodeGenerator = new DeliveryClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new DeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); Assert.NotNull(classCodeGenerator); Assert.True(classCodeGenerator.OverwriteExisting); @@ -26,22 +40,7 @@ public void Constructor_CreatesInstance() [Fact] public void Build_CreatesClassWithCompleteContentType() { - var classDefinition = new ClassDefinition("Complete content type"); - classDefinition.AddProperty(Property.FromContentTypeElement("text", "text")); - classDefinition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); - classDefinition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); - classDefinition.AddProperty(Property.FromContentTypeElement("number", "number")); - classDefinition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); - classDefinition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); - classDefinition.AddProperty(Property.FromContentTypeElement("asset", "asset")); - classDefinition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); - classDefinition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); - classDefinition.AddProperty(Property.FromContentTypeElement("url_slug", "url_slug")); - classDefinition.AddProperty(Property.FromContentTypeElement("custom", "custom")); - - classDefinition.AddSystemProperty(); - - var classCodeGenerator = new DeliveryClassCodeGenerator(classDefinition, classDefinition.ClassName); + var classCodeGenerator = new DeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); var compiledCode = classCodeGenerator.GenerateCode(); @@ -54,19 +53,7 @@ public void Build_CreatesClassWithCompleteContentType() [Fact] public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() { - var definition = new ClassDefinition("Complete content type"); - definition.AddProperty(Property.FromContentTypeElement("text", "text")); - definition.AddProperty(Property.FromContentTypeElement("rich_text", "rich_text")); - definition.AddProperty(Property.FromContentTypeElement("rich_text_structured", "rich_text(structured)")); - definition.AddProperty(Property.FromContentTypeElement("number", "number")); - definition.AddProperty(Property.FromContentTypeElement("multiple_choice", "multiple_choice")); - definition.AddProperty(Property.FromContentTypeElement("date_time", "date_time")); - definition.AddProperty(Property.FromContentTypeElement("asset", "asset")); - definition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); - definition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); - definition.AddProperty(Property.FromContentTypeElement("custom", "custom")); - - var classCodeGenerator = new DeliveryClassCodeGenerator(definition, definition.ClassName); + var classCodeGenerator = new DeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); var compiledCode = classCodeGenerator.GenerateCode(); var compilation = CSharpCompilation.Create( @@ -78,22 +65,6 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() }, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - var compilationErrors = "Compilation errors:\n"; - - if (!result.Success) - { - var failures = result.Diagnostics.Where(diagnostic => - diagnostic.IsWarningAsError || - diagnostic.Severity == DiagnosticSeverity.Error); - - foreach (var diagnostic in failures) - { - compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; - } - } - - Assert.True(result.Success, compilationErrors); + AssertCompiledCode(compilation); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs index 224fb2ee..feb005a9 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Linq; using System.Reflection; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Common; @@ -11,47 +10,47 @@ namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; -public class ManagementClassCodeGeneratorTests +public class ManagementClassCodeGeneratorTests : ClassCodeGeneratorTestsBase { - [Fact] - public void Constructor_CreatesInstance() + public ManagementClassCodeGeneratorTests() { - var classDefinition = new ClassDefinition("Complete content type"); - - var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); - - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); - } - - [Fact] - public void Build_CreatesClassWithCompleteContentType() - { - var classDefinition = new ClassDefinition("Complete content type"); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); - classDefinition.AddProperty(Property.FromContentTypeElement( + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); + } - var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); + [Fact] + public void Constructor_CreatesInstance() + { + var classCodeGenerator = new ManagementClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + + Assert.NotNull(classCodeGenerator); + Assert.True(classCodeGenerator.OverwriteExisting); + } + + [Fact] + public void Build_CreatesClassWithCompleteContentType() + { + var classCodeGenerator = new ManagementClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); var compiledCode = classCodeGenerator.GenerateCode(); @@ -65,28 +64,6 @@ public void Build_CreatesClassWithCompleteContentType() public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() { var classDefinition = new ClassDefinition("Complete content type"); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); - classDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); var classCodeGenerator = new ManagementClassCodeGenerator(classDefinition, classDefinition.ClassName); var compiledCode = classCodeGenerator.GenerateCode(); @@ -105,22 +82,6 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() }, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - using var ms = new MemoryStream(); - var result = compilation.Emit(ms); - var compilationErrors = "Compilation errors:\n"; - - if (!result.Success) - { - var failures = result.Diagnostics.Where(diagnostic => - diagnostic.IsWarningAsError || - diagnostic.Severity == DiagnosticSeverity.Error); - - foreach (var diagnostic in failures) - { - compilationErrors += $"{diagnostic.Id}: {diagnostic.GetMessage()}\n"; - } - } - - Assert.True(result.Success, compilationErrors); + AssertCompiledCode(compilation); } } From f99ca54268dee42914b77176b7125e4a75c52742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 22 Sep 2022 14:07:09 +0200 Subject: [PATCH 15/48] 90 introduce TypedExtendedDeliveryClassCodeGeneratorTests --- ...mpiledCode_TypedExtendedDeliveryModels.txt | 22 +++++ ...ExtendedDeliveryClassCodeGeneratorTests.cs | 94 +++++++++++++++++++ .../Kontent.Ai.ModelGenerator.Tests.csproj | 11 +++ 3 files changed, 127 insertions(+) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt new file mode 100644 index 00000000..d05a1120 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt @@ -0,0 +1,22 @@ +// +// This code was generated by a kontent-generators-net tool +// (see https://github.com/kontent-ai/model-generator-net). +// +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// For further modifications of the class, create a separate file with the partial class. +// + +using System; +using System.Linq; +using System.Collections.Generic; +using Kontent.Ai.Delivery.Abstractions; + +namespace KontentAiModels +{ + public partial class CompleteContentType + { + public Article ModularContentArticleSingle => ModularContentArticle.OfType
().FirstOrDefault(); + + public IEnumerable ModularContentHeroesTyped => ModularContentHeroes.OfType(); + } +} \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs new file mode 100644 index 00000000..540b9b24 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -0,0 +1,94 @@ +using Kontent.Ai.Management.Models.Types.Elements; +using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using System; +using System.IO; +using System.Reflection; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; +using Kontent.Ai.Management.Models.Shared; +using System.Collections.Generic; +using Kontent.Ai.Management.Models.Types; + +namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; + +public class TypedExtendedDeliveryClassCodeGeneratorTests : ClassCodeGeneratorTestsBase +{ + public TypedExtendedDeliveryClassCodeGeneratorTests() + { + // Linked items elements are limited to a single type with at least 1 item. + var singleAllowedTypeMultiItemsTypeName = "Hero"; + var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestHelper. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); + singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); + singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{singleAllowedTypeMultiItemsTypeName}>")); + + // Linked items element limited to a single type with at most or exactly 1 item. + var singleAllowedTypeExactlySingleItemTypeName = "Article"; + var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestHelper. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); + singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); + singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, singleAllowedTypeExactlySingleItemTypeName)); + } + + [Fact] + public void Constructor_CreatesInstance() + { + var classCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + + Assert.NotNull(classCodeGenerator); + Assert.True(classCodeGenerator.OverwriteExisting); + } + + [Fact] + public void Build_CreatesClassWithCompleteContentType() + { + var classCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + + var compiledCode = classCodeGenerator.GenerateCode(); + + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt"); + + Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + } + + [Fact] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + { + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + var compiledCode = classCodeGenerator.GenerateCode(); + + var heroClassDefinition = new ClassDefinition("Hero"); + var heroClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(heroClassDefinition, heroClassDefinition.ClassName); + var compiledHeroCode = heroClassCodeGenerator.GenerateCode(); + + var articleClassDefinition = new ClassDefinition("Article"); + var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); + var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); + + var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); + var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); + + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] + { + CSharpSyntaxTree.ParseText(compiledContentItemCode), + CSharpSyntaxTree.ParseText(compiledHeroCode), + CSharpSyntaxTree.ParseText(compiledArticleCode), + CSharpSyntaxTree.ParseText(compiledCode), + }, + references: new[] { + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq")).Location), + MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + AssertCompiledCode(compilation); + } +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj index 7a3e7818..7486232a 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj +++ b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj @@ -15,12 +15,23 @@ + + PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest From 3e080c5e5e8ec21ae3f2540fb6c8f69748dda7e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 22 Sep 2022 14:40:04 +0200 Subject: [PATCH 16/48] 90 TypedExtendedDeliveryClassCodeGenerator impl --- ...TypedExtendedDeliveryClassCodeGenerator.cs | 74 +++++++++++++++++-- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs index 2ce1e57f..52fee626 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs @@ -1,23 +1,87 @@ -using System; +using System.Collections; +using System.Linq; +using System.Text.RegularExpressions; using Kontent.Ai.ModelGenerator.Core.Common; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; public class TypedExtendedDeliveryClassCodeGenerator : ClassCodeGenerator { + private const string OfTypeName = "OfType"; + private const string FirstOrDefaultName = "FirstOrDefault"; + private const string SingleSuffix = "Single"; + private const string TypedSuffix = "Typed"; + public TypedExtendedDeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) : base(classDefinition, classFilename, @namespace) { } - protected override UsingDirectiveSyntax[] GetApiUsings() + protected override MemberDeclarationSyntax[] Properties => GetProperties(); + + protected override UsingDirectiveSyntax[] GetApiUsings() => new[] { - throw new NotImplementedException(); - } + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(nameof(System))), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Enumerable).Namespace!)), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(System.Collections.Generic.IEnumerable<>).Namespace!)), + SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Delivery.Abstractions.IApiResponse).Namespace!)) + }; protected override TypeDeclarationSyntax GetClassDeclaration() { - throw new NotImplementedException(); + var classDeclaration = base.GetClassDeclaration(); + + classDeclaration = classDeclaration.AddMembers(Properties); + + return classDeclaration; } + + private MemberDeclarationSyntax[] GetProperties() + { + var singleProperties = ClassDefinition.Properties + .Where(x => !x.TypeName.Contains(nameof(IEnumerable))) + .Select(element => SyntaxFactory + .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier + SingleSuffix) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .WithExpressionBody( + SyntaxFactory.ArrowExpressionClause( + SyntaxFactory.InvocationExpression( + SyntaxFactory.MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.InvocationExpression( + SyntaxFactory.MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.IdentifierName(element.Identifier), + SyntaxFactory.GenericName(SyntaxFactory.Identifier(OfTypeName)) + .WithTypeArgumentList(SyntaxFactory.TypeArgumentList( + SyntaxFactory.SingletonSeparatedList(SyntaxFactory.IdentifierName(element.TypeName)))))), + SyntaxFactory.IdentifierName(FirstOrDefaultName))))) + .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))); + + var enumeratedProperties = ClassDefinition.Properties + .Where(x => x.TypeName.Contains(nameof(IEnumerable))) + .Select(element => + { + var typeName = GetNonEnumerableTypeName(element.TypeName); + return SyntaxFactory + .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier + TypedSuffix) + .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) + .WithExpressionBody( + SyntaxFactory.ArrowExpressionClause( + SyntaxFactory.InvocationExpression( + SyntaxFactory.MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.IdentifierName(element.Identifier), + SyntaxFactory.GenericName(SyntaxFactory.Identifier(OfTypeName)) + .WithTypeArgumentList(SyntaxFactory.TypeArgumentList( + SyntaxFactory.SingletonSeparatedList(SyntaxFactory.IdentifierName(typeName)))))))) + .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); + }); + + return singleProperties.Union(enumeratedProperties).ToArray(); + } + + private static string GetNonEnumerableTypeName(string typeName) => Regex.Match(typeName, "[^\\>|\\<]\\w+\\b(? Date: Thu, 22 Sep 2022 15:28:40 +0200 Subject: [PATCH 17/48] 90 introduce FileSystemOutputProviderTests --- .../DeliveryCodeGeneratorTests.cs | 30 -------------- .../FileSystemOutputProviderTests.cs | 41 +++++++++++++++++++ .../ManagementCodeGeneratorTests.cs | 30 -------------- 3 files changed, 41 insertions(+), 60 deletions(-) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs diff --git a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs index ad0f4d53..a04461c5 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs @@ -38,36 +38,6 @@ public void Constructor_ManagementIsTrue_Throws() Assert.Throws(() => new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object)); } - [Fact] - public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() - { - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); - - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Empty(options.OutputDir); - Assert.NotEmpty(outputProvider.OutputDir); - } - - [Fact] - public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() - { - var expectedOutputDir = Environment.CurrentDirectory; - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); - - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); - } - [Theory] [InlineData(true)] [InlineData(false)] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs new file mode 100644 index 00000000..d03c3d17 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs @@ -0,0 +1,41 @@ +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Microsoft.Extensions.Options; +using Moq; +using System; +using System.IO; +using Xunit; + +namespace Kontent.Ai.ModelGenerator.Tests; + +public class FileSystemOutputProviderTests +{ + [Fact] + public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() + { + var mockOptions = new Mock>(); + var options = new CodeGeneratorOptions + { + OutputDir = "" + }; + mockOptions.Setup(x => x.Value).Returns(options); + + var outputProvider = new FileSystemOutputProvider(mockOptions.Object); + Assert.Empty(options.OutputDir); + Assert.NotEmpty(outputProvider.OutputDir); + } + + [Fact] + public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() + { + var expectedOutputDir = Environment.CurrentDirectory; + var mockOptions = new Mock>(); + var options = new CodeGeneratorOptions + { + OutputDir = "" + }; + mockOptions.Setup(x => x.Value).Returns(options); + + var outputProvider = new FileSystemOutputProvider(mockOptions.Object); + Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); + } +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs index 5db85460..36721081 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs @@ -46,36 +46,6 @@ public void Constructor_ManagementIsTrue_Throws() Assert.Throws(() => new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, _managementClient)); } - [Fact] - public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDirHasDefaultValue() - { - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); - - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Empty(options.OutputDir); - Assert.NotEmpty(outputProvider.OutputDir); - } - - [Fact] - public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() - { - var expectedOutputDir = Environment.CurrentDirectory; - var mockOptions = new Mock>(); - var options = new CodeGeneratorOptions - { - OutputDir = "" - }; - mockOptions.Setup(x => x.Value).Returns(options); - - var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); - } - [Fact] public void GetClassCodeGenerator_Returns() { From f5965a2502c0ca640b651654ddebea6ed3ff538d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 13 Oct 2022 14:26:53 +0200 Subject: [PATCH 18/48] 90 introduce TypedDeliveryPropertyMapper+ impl --- .../Helpers/TypedDeliveryPropertyMapper.cs | 104 ++++ .../TypedDeliveryPropertyMapperTests.cs | 585 ++++++++++++++++++ .../TestHelper.cs | 14 + 3 files changed, 703 insertions(+) create mode 100644 src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs new file mode 100644 index 00000000..033e0219 --- /dev/null +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -0,0 +1,104 @@ +using Kontent.Ai.Management.Models.Types.Elements; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Kontent.Ai.Management.Extensions; + +namespace Kontent.Ai.ModelGenerator.Core.Helpers; + +public static class TypedDeliveryPropertyMapper +{ + public static ICollection Map(ElementMetadataBase el, List contentTypes, CodeGeneratorOptions options) + { + Validate(contentTypes, options); + + var linkedItemsElement = el.ToElement(); + if (linkedItemsElement == null) + { + throw new ArgumentNullException(); + } + + if (!linkedItemsElement.AllowedTypes.Any() || + linkedItemsElement.AllowedTypes.Count() > 1) + { + return new List(); + } + + var allowedContentType = GetAllowedContentType(linkedItemsElement.AllowedTypes.First().Id.Value, contentTypes); + var allowedContentTypeCodename = TextHelpers.GetValidPascalCaseIdentifierName(allowedContentType.Codename); + + if (linkedItemsElement.ItemCountLimit is { Condition: LimitType.Exactly, Value: 1 }) + { + var singleAllowedContentTypeCodename = options.ExtendedDeliverPreviewModels + ? GetEnumerablePropertyTypeName(ContentItemClassCodeGenerator.DefaultContentItemClassName) + : allowedContentTypeCodename; + + return CreateEnumerableProperties(el, singleAllowedContentTypeCodename); + } + + var multipleAllowedContentTypeCodename = options.ExtendedDeliverPreviewModels + ? ContentItemClassCodeGenerator.DefaultContentItemClassName + : allowedContentTypeCodename; + + return CreateEnumerableProperties(el, multipleAllowedContentTypeCodename, allowedContentTypeCodename); + } + + private static void Validate(List contentTypes, CodeGeneratorOptions options) + { + if (contentTypes == null) + { + throw new ArgumentNullException(nameof(contentTypes)); + } + + if (!contentTypes.Any()) + { + throw new ArgumentException($"{nameof(contentTypes)} cannot be empty"); + } + + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (!options.ExtendedDeliveryModels()) + { + throw new ArgumentException("Can be used only for extended delivery models."); + } + } + + private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List contentTypes) + { + var allowedType = contentTypes.FirstOrDefault(type => allowedTypeId == type.Id); + + if (allowedType == null) + { + throw new ArgumentException("Could not find allowed type."); + } + + return allowedType; + } + + private static string GetEnumerablePropertyTypeName(string typeName) => $"{nameof(IEnumerable)}<{typeName}>"; + + private static string GetCompoundPropertyName(string codename, string typeName) => $"{codename}_{typeName}"; + + private static List GetPropertyAsList(Property property) => new List { property }; + + private static List CreateEnumerableProperties(ElementMetadataBase element, string elementType, string propertyName) => new List + { + Property.FromContentTypeElement( + element, + GetEnumerablePropertyTypeName(elementType), + GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)) + }; + + private static List CreateEnumerableProperties(ElementMetadataBase element, string elementType) => new List + { + Property.FromContentTypeElement(element, elementType) + }; +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs new file mode 100644 index 00000000..056609ea --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -0,0 +1,585 @@ +using Kontent.Ai.ModelGenerator.Core.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.Types.Elements; +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Xunit; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; + +namespace Kontent.Ai.ModelGenerator.Tests.Helpers; + +public class TypedDeliveryPropertyMapperTests +{ + private static readonly CodeGeneratorOptions ExtendedDeliverModelsOptions = new CodeGeneratorOptions + { + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = false + }; + + private static readonly CodeGeneratorOptions ExtendedDeliverPreviewModelsOptions = new CodeGeneratorOptions + { + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = true + }; + + [Fact] + public void Map_LinkedItemsElementIsNull_Throws() + { + var contentTypes = new List + { + new ContentTypeModel() + }; + var options = new CodeGeneratorOptions + { + ExtendedDeliverPreviewModels = false, + ExtendedDeliverModels = true + }; + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(null, contentTypes, options)); + } + + [Fact] + public void Map_NotLinkedItemsElement_Throws() + { + var contentTypes = new List + { + new ContentTypeModel() + }; + var element = new AssetElementMetadataModel(); + var options = new CodeGeneratorOptions + { + ExtendedDeliverPreviewModels = false, + ExtendedDeliverModels = true + }; + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, options)); + } + + [Fact] + public void Map_ContentTypesIsNull_Throws() + { + var element = new LinkedItemsElementMetadataModel(); + var options = new CodeGeneratorOptions + { + ExtendedDeliverPreviewModels = false, + ExtendedDeliverModels = true + }; + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, null, options)); + } + + [Fact] + public void Map_ContentTypesIsEmpty_Throws() + { + var contentTypes = new List(); + var element = new LinkedItemsElementMetadataModel(); + var options = new CodeGeneratorOptions + { + ExtendedDeliverPreviewModels = false, + ExtendedDeliverModels = true + }; + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, options)); + } + + [Fact] + public void Map_OptionsIsNull_Throws() + { + var contentTypes = new List + { + new ContentTypeModel() + }; + var element = new LinkedItemsElementMetadataModel(); + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, null)); + } + + [Fact] + public void Map_GeneralExtendedDeliveryModelsIsFalse_Throws() + { + var contentTypes = new List + { + new ContentTypeModel() + }; + var element = new LinkedItemsElementMetadataModel(); + var options = new CodeGeneratorOptions + { + ExtendedDeliverPreviewModels = false, + ExtendedDeliverModels = false + }; + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, options)); + } + + #region Live models + + [Fact] + public void Map_Live_CouldNotFindAllowedType_Throws() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }; + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions)); + } + + [Fact] + public void Map_Live_SingleAllowedTypeMultiItems_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + + Assert.Single(result); + Assert.Equal("Articles_Article", result.First().Codename); + Assert.Null(result.First().Id); + Assert.Equal("ArticlesArticle", result.First().Identifier); + Assert.Equal("IEnumerable
", result.First().TypeName); + } + + [Fact] + public void Map_Live_SingleAllowedTypeExactlySingleItem_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.Exactly, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + + Assert.Single(result); + Assert.Equal("article", result.First().Codename); + Assert.Null(result.First().Id); + Assert.Equal("Article", result.First().Identifier); + Assert.Equal("Article", result.First().TypeName); + } + + [Fact] + public void Map_Live_MultiAllowedTypesSingleItem_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.Exactly, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "blog", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + + Assert.Empty(result); + } + + [Fact] + public void Map_Live_MultiAllowedTypesMultiItems_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "blog", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + + Assert.Empty(result); + } + + #endregion + + #region Preview models + + [Fact] + public void Map_Preview_CouldNotFindAllowedType_Throws() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }; + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions)); + } + + [Fact] + public void Map_Preview_SingleAllowedTypeMultiItems_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + + Assert.Single(result); + Assert.Equal("Articles_Article", result.First().Codename); + Assert.Null(result.First().Id); + Assert.Equal("ArticlesArticle", result.First().Identifier); + Assert.Equal($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", result.First().TypeName); + } + + [Fact] + public void Map_Preview_SingleAllowedTypeExactlySingleItem_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.Exactly, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + + Assert.Single(result); + Assert.Equal("article", result.First().Codename); + Assert.Null(result.First().Id); + Assert.Equal("Article", result.First().Identifier); + Assert.Equal("IEnumerable", result.First().TypeName); + } + + [Fact] + public void Map_Preview_MultiAllowedTypesSingleItem_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.Exactly, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "blog", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + + Assert.Empty(result); + } + + [Fact] + public void Map_Preview_MultiAllowedTypesMultiItems_Returns() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "blog", + Id = Guid.NewGuid() + } + }; + + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var element = TestHelper.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)); + + var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + + Assert.Empty(result); + } + + #endregion +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs index d09b39b9..77bf3a99 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs @@ -1,4 +1,8 @@ using System; +using System.Collections.Generic; +using Kontent.Ai.Management.Models.Shared; +using System.Linq; +using Kontent.Ai.Management.Models.Types; using Kontent.Ai.Management.Models.Types.Elements; using Newtonsoft.Json.Linq; @@ -23,4 +27,14 @@ public static ElementMetadataBase GenerateGuidelinesElement(Guid elementId, stri guidelines = "guidelines" }).ToObject(); + + public static LinkedItemsElementMetadataModel GenerateLinkedItemsElement(string elementId, string elementCodename, LimitModel limitModel, IEnumerable allowedTypesIds) + { + var element = (LinkedItemsElementMetadataModel)GenerateElementMetadataBase(Guid.Parse(elementId), elementCodename, ElementMetadataType.LinkedItems); + + element.AllowedTypes = allowedTypesIds.Select(Reference.ById); + element.ItemCountLimit = limitModel; + + return element; + } } From 8290e765bd7612f02bb7b9f2870ffc7dc8b10f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 20 Oct 2022 15:59:14 +0200 Subject: [PATCH 19/48] 90 include ExtendedDeliveryClassCodeGenerator to ClassCodeGeneratorFactory --- .../Common/ClassCodeGeneratorFactory.cs | 9 ++++- .../Common/ClassCodeGeneratorFactoryTests.cs | 40 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs index 5069edcf..4b4ddb18 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs @@ -28,8 +28,13 @@ public static ClassCodeGenerator CreateClassCodeGenerator(CodeGeneratorOptions o return new PartialClassCodeGenerator(classDefinition, classFilename, options.Namespace); } - return options.ManagementApi - ? new ManagementClassCodeGenerator(classDefinition, classFilename, options.Namespace) + if (options.ManagementApi()) + { + return new ManagementClassCodeGenerator(classDefinition, classFilename, options.Namespace); + } + + return options.ExtendedDeliveryModels() + ? new ExtendedDeliveryClassCodeGenerator(classDefinition, classFilename, options.Namespace) : new DeliveryClassCodeGenerator(classDefinition, classFilename, options.Namespace); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs index 4fd733d6..bbfffe7c 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs @@ -59,6 +59,25 @@ public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_NoCustomPartialP AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_NoCustomPartialProperty_Returns(bool extendedDeliverPreviewModels) + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var codeGeneratorOptions = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); + + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); + } + [Theory] [InlineData(false)] [InlineData(true)] @@ -110,6 +129,27 @@ public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_CustomNamespace_ AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_CustomNamespace_Returns(bool extendedDeliverPreviewModels) + { + var classDefinitionCodename = "codename"; + var classFileName = "classFileName"; + var customNamespace = "CustomNameSpace"; + var codeGeneratorOptions = new CodeGeneratorOptions + { + ManagementApi = false, + Namespace = customNamespace, + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }; + + var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); + + AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); + } + [Fact] public void CreateClassCodeGenerator_ManagementClassCodeGenerator_NoCustomPartialProperty_Returns() { From c2fa2e164a9d0e717efadf3fbd19b7765c9dff2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 10 Nov 2022 14:38:14 +0100 Subject: [PATCH 20/48] 90 refactor test data generation --- .../Common/PropertyTests.cs | 25 ++--- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 29 +++--- .../ManagementClassCodeGeneratorTests.cs | 23 ++--- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 5 +- .../Helpers/ManagementElementHelperTests.cs | 19 ++-- .../TypedDeliveryPropertyMapperTests.cs | 21 +++-- .../ManagementCodeGeneratorTests.cs | 3 +- .../TestHelpers/LinkedItemsContentTypeData.cs | 92 +++++++++++++++++++ .../TestDataGenerator.cs} | 4 +- 9 files changed, 160 insertions(+), 61 deletions(-) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs rename test/Kontent.Ai.ModelGenerator.Tests/{TestHelper.cs => TestHelpers/TestDataGenerator.cs} (93%) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs index 379683e7..841d6fa8 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs @@ -3,6 +3,7 @@ using System.Linq; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests.Common; @@ -75,33 +76,33 @@ public void FromContentTypeElement_DeliveryApiModel_InvalidContentTypeElement_Th public void FromContentTypeElement_ManagementApiModel_GuidelinesElement_Throws() { Assert.Throws(() => - Property.FromContentTypeElement(TestHelper.GenerateGuidelinesElement(Guid.NewGuid(), "codename"))); + Property.FromContentTypeElement(TestDataGenerator.GenerateGuidelinesElement(Guid.NewGuid(), "codename"))); } public static IEnumerable ManagementElements => new List<(string, string, ElementMetadataBase)> { ("TextElement", "TextElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "text_element")), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "text_element")), ("RichTextElement","RichTextElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "rich_text_element", ElementMetadataType.RichText)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "rich_text_element", ElementMetadataType.RichText)), ("NumberElement", "NumberElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "number_element", ElementMetadataType.Number)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "number_element", ElementMetadataType.Number)), ("MultipleChoiceElement","MultipleChoiceElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "multiple_choice_element", ElementMetadataType.MultipleChoice)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "multiple_choice_element", ElementMetadataType.MultipleChoice)), ("DateTimeElement","DateTimeElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "date_time_element", ElementMetadataType.DateTime)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "date_time_element", ElementMetadataType.DateTime)), ("AssetElement", "AssetElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "asset_element", ElementMetadataType.Asset)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "asset_element", ElementMetadataType.Asset)), ("LinkedItemsElement", "LinkedItemsElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "linked_items_element", ElementMetadataType.LinkedItems)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "linked_items_element", ElementMetadataType.LinkedItems)), ("SubpagesElement", "SubpagesElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "subpages_element", ElementMetadataType.Subpages)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "subpages_element", ElementMetadataType.Subpages)), ("TaxonomyElement", "TaxonomyElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "taxonomy_element", ElementMetadataType.Taxonomy)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "taxonomy_element", ElementMetadataType.Taxonomy)), ("UrlSlugElement", "UrlSlugElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "url_slug_element", ElementMetadataType.UrlSlug)), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "url_slug_element", ElementMetadataType.UrlSlug)), ("CustomElement", "CustomElement", - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), "custom_element", ElementMetadataType.Custom)) + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), "custom_element", ElementMetadataType.Custom)) }.Select(triple => new object[] { triple.Item1, triple.Item2, triple.Item3 }); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index 6a34bb26..d22e5c4c 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis; using Xunit; using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -18,32 +19,32 @@ public class ExtendedDeliveryClassCodeGeneratorTests : ClassCodeGeneratorTestsBa public ExtendedDeliveryClassCodeGeneratorTests() { ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"), ElementMetadataType.Text.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText), ElementMetadataType.RichText.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number), ElementMetadataType.Number.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice), ElementMetadataType.MultipleChoice.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime), ElementMetadataType.DateTime.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset), ElementMetadataType.Asset.ToString())); // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItemsTypeName = "Hero"; - var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestHelper. + var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; @@ -51,14 +52,14 @@ public ExtendedDeliveryClassCodeGeneratorTests() // Linked items element limited to a single type with at most or exactly 1 item. var singleAllowedTypeExactlySingleItemTypeName = "Article"; - var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestHelper. + var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. - var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestHelper. + var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "modular_content_blog", ElementMetadataType.LinkedItems); multiAllowedTypesSingleItem.AllowedTypes = new List(new List { @@ -69,7 +70,7 @@ public ExtendedDeliveryClassCodeGeneratorTests() ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesSingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); // Linked items element limited to multiple types with at least 1 item. - var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestHelper. + var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); multiAllowedTypesMultiItems.AllowedTypes = new List(new List { @@ -80,19 +81,19 @@ public ExtendedDeliveryClassCodeGeneratorTests() ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), ElementMetadataType.RichText + Property.StructuredSuffix)); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy), ElementMetadataType.Taxonomy.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug), ElementMetadataType.UrlSlug.ToString())); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom), + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom), ElementMetadataType.Custom.ToString())); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs index feb005a9..77bad95e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs @@ -4,6 +4,7 @@ using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; @@ -15,27 +16,27 @@ public class ManagementClassCodeGeneratorTests : ClassCodeGeneratorTestsBase public ManagementClassCodeGeneratorTests() { ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("6712e528-8504-4a36-b716-a28327d6205f"), "text"))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("014d2125-923d-4428-93b4-ad1590274912"), "rich_text", ElementMetadataType.RichText))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("9d23ff46-117c-432c-8fb2-3273acfbbbf5"), "number", ElementMetadataType.Number))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("2115b9ad-5df5-45b8-aa0f-490b5119afa6"), "multiple_choice", ElementMetadataType.MultipleChoice))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a90"), "date_time", ElementMetadataType.DateTime))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content", ElementMetadataType.LinkedItems))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("44924563-44d4-4272-a20f-b8745698b082"), "subpages", ElementMetadataType.Subpages))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug))); ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestHelper.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom))); } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index 540b9b24..c70e8d7e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -10,6 +10,7 @@ using Kontent.Ai.Management.Models.Shared; using System.Collections.Generic; using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -19,7 +20,7 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() { // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItemsTypeName = "Hero"; - var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestHelper. + var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; @@ -27,7 +28,7 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() // Linked items element limited to a single type with at most or exactly 1 item. var singleAllowedTypeExactlySingleItemTypeName = "Article"; - var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestHelper. + var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs index fa744d60..ef8c442f 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs @@ -4,6 +4,7 @@ using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.Management.Models.TypeSnippets; using Kontent.Ai.ModelGenerator.Core.Helpers; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests.Helpers; @@ -38,7 +39,7 @@ public void GetManagementContentTypeSnippetElements_NoSnippetElements_Throws() } }; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets); @@ -51,7 +52,7 @@ public void GetManagementContentTypeSnippetElements_NoSnippets_Throws() { var contentTypeElementCodename = "codename"; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, new List())); } @@ -62,7 +63,7 @@ public void GetManagementContentTypeSnippetElements_NoMatchingSnippet_Throws() var contentTypeElementCodename = "codename"; var snippetCodename = "other_snippet_codename"; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); var snippets = new List { @@ -71,8 +72,8 @@ public void GetManagementContentTypeSnippetElements_NoMatchingSnippet_Throws() Codename = snippetCodename, Elements = new List { - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el"), - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el2", ElementMetadataType.Number) + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el"), + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), $"{snippetCodename}el2", ElementMetadataType.Number) } } }; @@ -85,7 +86,7 @@ public void GetManagementContentTypeSnippetElements_NotManagementContentTypeSnip { var snippetCodename = "codename"; - var element = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename); + var element = TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename); var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, new List()); @@ -99,7 +100,7 @@ public void GetManagementContentTypeSnippetElements_Returns() var expectedElement2Id = Guid.NewGuid(); var snippetCodename = "snippet_codename"; - var snippetElement = TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename, ElementMetadataType.ContentTypeSnippet); + var snippetElement = TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), snippetCodename, ElementMetadataType.ContentTypeSnippet); var snippets = new List { @@ -108,8 +109,8 @@ public void GetManagementContentTypeSnippetElements_Returns() Codename = snippetCodename, Elements = new List { - TestHelper.GenerateElementMetadataBase(expectedElementId, $"{snippetCodename}_el"), - TestHelper.GenerateElementMetadataBase(expectedElement2Id, $"{snippetCodename}_el2", ElementMetadataType.Number) + TestDataGenerator.GenerateElementMetadataBase(expectedElementId, $"{snippetCodename}_el"), + TestDataGenerator.GenerateElementMetadataBase(expectedElement2Id, $"{snippetCodename}_el2", ElementMetadataType.Number) } } }; diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 056609ea..09aa440a 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -7,6 +7,7 @@ using Kontent.Ai.ModelGenerator.Core.Configuration; using Xunit; using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; namespace Kontent.Ai.ModelGenerator.Tests.Helpers; @@ -147,7 +148,7 @@ public void Map_Live_CouldNotFindAllowedType_Throws() } }; - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "articles", limitModel, @@ -188,7 +189,7 @@ public void Map_Live_SingleAllowedTypeMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "articles", limitModel, @@ -235,7 +236,7 @@ public void Map_Live_SingleAllowedTypeExactlySingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "article", limitModel, @@ -287,7 +288,7 @@ public void Map_Live_MultiAllowedTypesSingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "article", limitModel, @@ -335,7 +336,7 @@ public void Map_Live_MultiAllowedTypesMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "articles", limitModel, @@ -382,7 +383,7 @@ public void Map_Preview_CouldNotFindAllowedType_Throws() } }; - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "articles", limitModel, @@ -423,7 +424,7 @@ public void Map_Preview_SingleAllowedTypeMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "articles", limitModel, @@ -470,7 +471,7 @@ public void Map_Preview_SingleAllowedTypeExactlySingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "article", limitModel, @@ -522,7 +523,7 @@ public void Map_Preview_MultiAllowedTypesSingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "article", limitModel, @@ -570,7 +571,7 @@ public void Map_Preview_MultiAllowedTypesMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestHelper.GenerateLinkedItemsElement( + var element = TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), "articles", limitModel, diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs index 36721081..2b1a90a0 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs @@ -12,6 +12,7 @@ using Kontent.Ai.ModelGenerator.Core; using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Tests.Fixtures; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; using Microsoft.Extensions.Options; using Moq; using Xunit; @@ -65,7 +66,7 @@ public void GetClassCodeGenerator_Returns() Codename = contentTypeCodename, Elements = new List { - TestHelper.GenerateElementMetadataBase(Guid.NewGuid(), elementCodename) + TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), elementCodename) } }; diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs new file mode 100644 index 00000000..2336e9d3 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using Kontent.Ai.Management.Models.Shared; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.Types.Elements; + +namespace Kontent.Ai.ModelGenerator.Tests.TestHelpers; + +public static class LinkedItemsContentTypeData +{ + public static ContentTypeModel HeroContentType = new ContentTypeModel + { + Name = "Hero", + Id = Guid.NewGuid(), + Codename = "hero" + }; + + public static ContentTypeModel ArticleContentType = new ContentTypeModel + { + Name = "Article", + Id = Guid.NewGuid(), + Codename = "article" + }; + + /// + /// Represents linked items element limited to a single type with at least 1 item + /// + public static LinkedItemsElementMetadataModel SingleAllowedTypeMultiItems = GenerateSingleAllowedTypeMultiItems(); + + /// + /// Represents linked items element limited to a single type with at most or exactly 1 item + /// + public static LinkedItemsElementMetadataModel SingleAllowedTypeExactlySingleItem = GenerateSingleAllowedTypeExactlySingleItem(); + + /// + /// Represents linked items element limited to multiple types with at least 1 at most or exactly 1 item + /// + public static LinkedItemsElementMetadataModel MultiAllowedTypesSingleItem = GenerateMultiAllowedTypesSingleItem(); + + /// + /// Represents linked items element limited to multiple types with at least 1 item + /// + public static LinkedItemsElementMetadataModel MultiAllowedTypesMultiItems = GenerateMultiAllowedTypesMultiItems(); + + private static LinkedItemsElementMetadataModel GenerateSingleAllowedTypeMultiItems() + { + var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); + singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ById(HeroContentType.Id) }); + singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + + return singleAllowedTypeMultiItems; + } + + private static LinkedItemsElementMetadataModel GenerateSingleAllowedTypeExactlySingleItem() + { + var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); + singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ById(ArticleContentType.Id) }); + singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + + return singleAllowedTypeExactlySingleItem; + } + + private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesSingleItem() + { + var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "modular_content_blog", ElementMetadataType.LinkedItems); + multiAllowedTypesSingleItem.AllowedTypes = new List(new List + { + Reference.ById(HeroContentType.Id), + Reference.ById(ArticleContentType.Id) + }); + multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + + return multiAllowedTypesSingleItem; + } + + private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesMultiItems() + { + var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); + multiAllowedTypesMultiItems.AllowedTypes = new List(new List + { + Reference.ById(HeroContentType.Id), + Reference.ById(ArticleContentType.Id) + }); + multiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + + return multiAllowedTypesMultiItems; + } +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs similarity index 93% rename from test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs rename to test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs index 77bf3a99..fa696fc6 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelper.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs @@ -6,9 +6,9 @@ using Kontent.Ai.Management.Models.Types.Elements; using Newtonsoft.Json.Linq; -namespace Kontent.Ai.ModelGenerator.Tests; +namespace Kontent.Ai.ModelGenerator.Tests.TestHelpers; -internal static class TestHelper +internal static class TestDataGenerator { public static ElementMetadataBase GenerateElementMetadataBase(Guid elementId, string elementCodename, ElementMetadataType type = ElementMetadataType.Text) => JObject.FromObject(new From eaa0e22c96ca1fb37beb2ccd7e4dee3b0e007ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 10 Nov 2022 15:18:45 +0100 Subject: [PATCH 21/48] 90 refactor typed property mapper --- .../Helpers/TypedDeliveryPropertyMapper.cs | 33 +++-- .../TypedDeliveryPropertyMapperTests.cs | 119 +++++++++--------- 2 files changed, 78 insertions(+), 74 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index 033e0219..cc5a1251 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -13,7 +13,11 @@ namespace Kontent.Ai.ModelGenerator.Core.Helpers; public static class TypedDeliveryPropertyMapper { - public static ICollection Map(ElementMetadataBase el, List contentTypes, CodeGeneratorOptions options) + public static bool TryMap( + ElementMetadataBase el, + List contentTypes, + CodeGeneratorOptions options, + out Property typedProperty) { Validate(contentTypes, options); @@ -26,7 +30,8 @@ public static ICollection Map(ElementMetadataBase el, List 1) { - return new List(); + typedProperty = null; + return false; } var allowedContentType = GetAllowedContentType(linkedItemsElement.AllowedTypes.First().Id.Value, contentTypes); @@ -38,14 +43,16 @@ public static ICollection Map(ElementMetadataBase el, List contentTypes, CodeGeneratorOptions options) @@ -87,18 +94,8 @@ private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List $"{codename}_{typeName}"; - private static List GetPropertyAsList(Property property) => new List { property }; - - private static List CreateEnumerableProperties(ElementMetadataBase element, string elementType, string propertyName) => new List - { - Property.FromContentTypeElement( - element, - GetEnumerablePropertyTypeName(elementType), - GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)) - }; - - private static List CreateEnumerableProperties(ElementMetadataBase element, string elementType) => new List - { - Property.FromContentTypeElement(element, elementType) - }; + private static Property CreateProperty(ElementMetadataBase element, string elementType, string propertyName) => Property.FromContentTypeElement( + element, + GetEnumerablePropertyTypeName(elementType), + GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 09aa440a..46de8e56 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -26,7 +26,7 @@ public class TypedDeliveryPropertyMapperTests }; [Fact] - public void Map_LinkedItemsElementIsNull_Throws() + public void TryMap_LinkedItemsElementIsNull_Throws() { var contentTypes = new List { @@ -38,11 +38,11 @@ public void Map_LinkedItemsElementIsNull_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(null, contentTypes, options)); + Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, options, out _)); } [Fact] - public void Map_NotLinkedItemsElement_Throws() + public void TryMap_NotLinkedItemsElement_Throws() { var contentTypes = new List { @@ -55,11 +55,11 @@ public void Map_NotLinkedItemsElement_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, options)); + Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _)); } [Fact] - public void Map_ContentTypesIsNull_Throws() + public void TryMap_ContentTypesIsNull_Throws() { var element = new LinkedItemsElementMetadataModel(); var options = new CodeGeneratorOptions @@ -68,11 +68,11 @@ public void Map_ContentTypesIsNull_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, null, options)); + Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, null, options, out _)); } [Fact] - public void Map_ContentTypesIsEmpty_Throws() + public void TryMap_ContentTypesIsEmpty_Throws() { var contentTypes = new List(); var element = new LinkedItemsElementMetadataModel(); @@ -82,11 +82,11 @@ public void Map_ContentTypesIsEmpty_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, options)); + Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _)); } [Fact] - public void Map_OptionsIsNull_Throws() + public void TryMap_OptionsIsNull_Throws() { var contentTypes = new List { @@ -94,11 +94,11 @@ public void Map_OptionsIsNull_Throws() }; var element = new LinkedItemsElementMetadataModel(); - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, null)); + Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, null, out _)); } [Fact] - public void Map_GeneralExtendedDeliveryModelsIsFalse_Throws() + public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws() { var contentTypes = new List { @@ -111,13 +111,13 @@ public void Map_GeneralExtendedDeliveryModelsIsFalse_Throws() ExtendedDeliverModels = false }; - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, contentTypes, options)); + Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _)); } #region Live models [Fact] - public void Map_Live_CouldNotFindAllowedType_Throws() + public void TryMap_Live_CouldNotFindAllowedType_Throws() { var limitModel = new LimitModel { @@ -154,11 +154,12 @@ public void Map_Live_CouldNotFindAllowedType_Throws() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions)); + Assert.Throws(() => + TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out _)); } [Fact] - public void Map_Live_SingleAllowedTypeMultiItems_Returns() + public void TryMap_Live_SingleAllowedTypeMultiItems_Returns() { var limitModel = new LimitModel { @@ -195,17 +196,18 @@ public void Map_Live_SingleAllowedTypeMultiItems_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.Single(result); - Assert.Equal("Articles_Article", result.First().Codename); - Assert.Null(result.First().Id); - Assert.Equal("ArticlesArticle", result.First().Identifier); - Assert.Equal("IEnumerable
", result.First().TypeName); + Assert.True(result); + Assert.NotNull(typedProperty); + Assert.Equal("Articles_Article", typedProperty.Codename); + Assert.Null(typedProperty.Id); + Assert.Equal("ArticlesArticle", typedProperty.Identifier); + Assert.Equal("IEnumerable
", typedProperty.TypeName); } [Fact] - public void Map_Live_SingleAllowedTypeExactlySingleItem_Returns() + public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns() { var limitModel = new LimitModel { @@ -242,17 +244,17 @@ public void Map_Live_SingleAllowedTypeExactlySingleItem_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.Single(result); - Assert.Equal("article", result.First().Codename); - Assert.Null(result.First().Id); - Assert.Equal("Article", result.First().Identifier); - Assert.Equal("Article", result.First().TypeName); + Assert.True(result); + Assert.Equal("article", typedProperty.Codename); + Assert.Null(typedProperty.Id); + Assert.Equal("Article", typedProperty.Identifier); + Assert.Equal("Article", typedProperty.TypeName); } [Fact] - public void Map_Live_MultiAllowedTypesSingleItem_Returns() + public void TryMap_Live_MultiAllowedTypesSingleItem_Returns() { var limitModel = new LimitModel { @@ -294,13 +296,14 @@ public void Map_Live_MultiAllowedTypesSingleItem_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.Empty(result); + Assert.False(result); + Assert.Null(typedProperty); } [Fact] - public void Map_Live_MultiAllowedTypesMultiItems_Returns() + public void TryMap_Live_MultiAllowedTypesMultiItems_Returns() { var limitModel = new LimitModel { @@ -342,9 +345,10 @@ public void Map_Live_MultiAllowedTypesMultiItems_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.Empty(result); + Assert.False(result); + Assert.Null(typedProperty); } #endregion @@ -352,7 +356,7 @@ public void Map_Live_MultiAllowedTypesMultiItems_Returns() #region Preview models [Fact] - public void Map_Preview_CouldNotFindAllowedType_Throws() + public void TryMap_Preview_CouldNotFindAllowedType_Throws() { var limitModel = new LimitModel { @@ -389,11 +393,12 @@ public void Map_Preview_CouldNotFindAllowedType_Throws() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - Assert.Throws(() => TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions)); + Assert.Throws(() => + TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out _)); } [Fact] - public void Map_Preview_SingleAllowedTypeMultiItems_Returns() + public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns() { var limitModel = new LimitModel { @@ -430,17 +435,17 @@ public void Map_Preview_SingleAllowedTypeMultiItems_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.Single(result); - Assert.Equal("Articles_Article", result.First().Codename); - Assert.Null(result.First().Id); - Assert.Equal("ArticlesArticle", result.First().Identifier); - Assert.Equal($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", result.First().TypeName); + Assert.True(result); + Assert.Equal("Articles_Article", typedProperty.Codename); + Assert.Null(typedProperty.Id); + Assert.Equal("ArticlesArticle", typedProperty.Identifier); + Assert.Equal($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", typedProperty.TypeName); } [Fact] - public void Map_Preview_SingleAllowedTypeExactlySingleItem_Returns() + public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns() { var limitModel = new LimitModel { @@ -477,17 +482,17 @@ public void Map_Preview_SingleAllowedTypeExactlySingleItem_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.Single(result); - Assert.Equal("article", result.First().Codename); - Assert.Null(result.First().Id); - Assert.Equal("Article", result.First().Identifier); - Assert.Equal("IEnumerable", result.First().TypeName); + Assert.True(result); + Assert.Equal("article", typedProperty.Codename); + Assert.Null(typedProperty.Id); + Assert.Equal("Article", typedProperty.Identifier); + Assert.Equal("IEnumerable", typedProperty.TypeName); } [Fact] - public void Map_Preview_MultiAllowedTypesSingleItem_Returns() + public void TryMap_Preview_MultiAllowedTypesSingleItem_Returns() { var limitModel = new LimitModel { @@ -529,13 +534,14 @@ public void Map_Preview_MultiAllowedTypesSingleItem_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.Empty(result); + Assert.False(result); + Assert.Null(typedProperty); } [Fact] - public void Map_Preview_MultiAllowedTypesMultiItems_Returns() + public void TryMap_Preview_MultiAllowedTypesMultiItems_Returns() { var limitModel = new LimitModel { @@ -577,9 +583,10 @@ public void Map_Preview_MultiAllowedTypesMultiItems_Returns() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.Map(element, allContentTypes, ExtendedDeliverPreviewModelsOptions); + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.Empty(result); + Assert.False(result); + Assert.Null(typedProperty); } #endregion From fb3f13a8bcf482ec20605de04b8dba8069e7d775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 10 Nov 2022 22:48:46 +0100 Subject: [PATCH 22/48] 90 fix original property name --- .../Class/TypedExtendedDeliveryClassCodeGenerator.cs | 12 +++++++++++- ...Type_CompiledCode_TypedExtendedDeliveryModels.txt | 2 +- .../TypedExtendedDeliveryClassCodeGeneratorTests.cs | 11 ++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs index 52fee626..fad95e8b 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs @@ -73,7 +73,7 @@ private MemberDeclarationSyntax[] GetProperties() SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, - SyntaxFactory.IdentifierName(element.Identifier), + SyntaxFactory.IdentifierName(GetOriginalPropertyName(element.Identifier, typeName)), SyntaxFactory.GenericName(SyntaxFactory.Identifier(OfTypeName)) .WithTypeArgumentList(SyntaxFactory.TypeArgumentList( SyntaxFactory.SingletonSeparatedList(SyntaxFactory.IdentifierName(typeName)))))))) @@ -84,4 +84,14 @@ private MemberDeclarationSyntax[] GetProperties() } private static string GetNonEnumerableTypeName(string typeName) => Regex.Match(typeName, "[^\\>|\\<]\\w+\\b(? ModularContentArticle.OfType
().FirstOrDefault(); - public IEnumerable ModularContentHeroesTyped => ModularContentHeroes.OfType(); + public IEnumerable ModularContentHeroesHeroTyped => ModularContentHeroes.OfType(); } } \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index c70e8d7e..16f628ec 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -2,6 +2,7 @@ using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using System; +using System.Collections; using System.IO; using System.Reflection; using Microsoft.CodeAnalysis; @@ -20,16 +21,20 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() { // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItemsTypeName = "Hero"; + var singleAllowedTypeMultiItemsTypeCodename = "modular_content_heroes"; var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. - GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); + GenerateElementMetadataBase(Guid.NewGuid(), singleAllowedTypeMultiItemsTypeCodename, ElementMetadataType.LinkedItems); singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{singleAllowedTypeMultiItemsTypeName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement( + singleAllowedTypeMultiItems, + $"{nameof(IEnumerable)}<{singleAllowedTypeMultiItemsTypeName}>", + $"{singleAllowedTypeMultiItemsTypeCodename}_{singleAllowedTypeMultiItemsTypeName}")); // Linked items element limited to a single type with at most or exactly 1 item. var singleAllowedTypeExactlySingleItemTypeName = "Article"; var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. - GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); + GenerateElementMetadataBase(Guid.NewGuid(), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, singleAllowedTypeExactlySingleItemTypeName)); From 7369338c5755ba3acbf669174b13551f9f41c6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 10 Nov 2022 22:56:18 +0100 Subject: [PATCH 23/48] 90 introduce GetEnumerableType helper method --- .../Common/Property.cs | 15 +++++++-------- .../Helpers/TextHelpers.cs | 11 +++++++++++ .../Helpers/TypedDeliveryPropertyMapper.cs | 6 ++---- ...dExtendedDeliveryClassCodeGeneratorTests.cs | 4 ++-- .../Helpers/TextHelpersTests.cs | 18 ++++++++++++++++++ 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 20977205..806ef101 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Globalization; using Kontent.Ai.Delivery.Abstractions; @@ -30,11 +29,11 @@ public class Property { "rich_text", "string" }, { "rich_text" + StructuredSuffix, nameof(IRichTextContent)}, { "number", "decimal?" }, - { "multiple_choice", $"{nameof(IEnumerable)}<{nameof(IMultipleChoiceOption)}>"}, + { "multiple_choice", TextHelpers.GetEnumerableType(nameof(IMultipleChoiceOption))}, { "date_time", "DateTime?" }, - { "asset", $"{nameof(IEnumerable)}<{nameof(IAsset)}>" }, - { "modular_content", $"{nameof(IEnumerable)}<{nameof(Object).ToLower(CultureInfo.InvariantCulture)}>" }, - { "taxonomy", $"{nameof(IEnumerable)}<{nameof(ITaxonomyTerm)}>" }, + { "asset", TextHelpers.GetEnumerableType(nameof(IAsset)) }, + { "modular_content", TextHelpers.GetEnumerableType(nameof(Object).ToLower(CultureInfo.InvariantCulture)) }, + { "taxonomy", TextHelpers.GetEnumerableType(nameof(ITaxonomyTerm)) }, { "url_slug", "string" }, { "custom", "string" } }; @@ -45,11 +44,11 @@ public class Property { ElementMetadataType.RichText.ToString(), "string" }, { ElementMetadataType.RichText + StructuredSuffix, nameof(IRichTextContent)}, { ElementMetadataType.Number.ToString(), "decimal?" }, - { ElementMetadataType.MultipleChoice.ToString(), $"{nameof(IEnumerable)}<{nameof(IMultipleChoiceOption)}>"}, + { ElementMetadataType.MultipleChoice.ToString(), TextHelpers.GetEnumerableType(nameof(IMultipleChoiceOption))}, { ElementMetadataType.DateTime.ToString(), "DateTime?" }, - { ElementMetadataType.Asset.ToString(), $"{nameof(IEnumerable)}<{nameof(IAsset)}>" }, + { ElementMetadataType.Asset.ToString(), TextHelpers.GetEnumerableType(nameof(IAsset)) }, { ElementMetadataType.LinkedItems.ToString(), null }, - { ElementMetadataType.Taxonomy.ToString(), $"{nameof(IEnumerable)}<{nameof(ITaxonomyTerm)}>" }, + { ElementMetadataType.Taxonomy.ToString(), TextHelpers.GetEnumerableType(nameof(ITaxonomyTerm)) }, { ElementMetadataType.UrlSlug.ToString(), "string" }, { ElementMetadataType.Custom.ToString(), "string" } }; diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs index 21a67ea7..3b26716f 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Linq; using System.Text.RegularExpressions; using Kontent.Ai.ModelGenerator.Core.Common; @@ -52,4 +53,14 @@ public static string GenerateCommentString(string customComment) {customComment} // {Environment.NewLine}{Environment.NewLine}"; } + + public static string GetEnumerableType(string typeName) + { + if (string.IsNullOrWhiteSpace(typeName)) + { + throw new ArgumentException("", nameof(typeName)); + } + + return $"{nameof(IEnumerable)}<{typeName}>"; + } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index cc5a1251..d23fe4d6 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -40,7 +40,7 @@ public static bool TryMap( if (linkedItemsElement.ItemCountLimit is { Condition: LimitType.Exactly, Value: 1 }) { var singleAllowedContentTypeCodename = options.ExtendedDeliverPreviewModels - ? GetEnumerablePropertyTypeName(ContentItemClassCodeGenerator.DefaultContentItemClassName) + ? TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName) : allowedContentTypeCodename; typedProperty = Property.FromContentTypeElement(el, singleAllowedContentTypeCodename); @@ -90,12 +90,10 @@ private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List $"{nameof(IEnumerable)}<{typeName}>"; - private static string GetCompoundPropertyName(string codename, string typeName) => $"{codename}_{typeName}"; private static Property CreateProperty(ElementMetadataBase element, string elementType, string propertyName) => Property.FromContentTypeElement( element, - GetEnumerablePropertyTypeName(elementType), + TextHelpers.GetEnumerableType(elementType), GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index 16f628ec..be44a148 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -2,7 +2,6 @@ using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using System; -using System.Collections; using System.IO; using System.Reflection; using Microsoft.CodeAnalysis; @@ -11,6 +10,7 @@ using Kontent.Ai.Management.Models.Shared; using System.Collections.Generic; using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.ModelGenerator.Core.Helpers; using Kontent.Ai.ModelGenerator.Tests.TestHelpers; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -28,7 +28,7 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement( singleAllowedTypeMultiItems, - $"{nameof(IEnumerable)}<{singleAllowedTypeMultiItemsTypeName}>", + TextHelpers.GetEnumerableType(singleAllowedTypeMultiItemsTypeName), $"{singleAllowedTypeMultiItemsTypeCodename}_{singleAllowedTypeMultiItemsTypeName}")); // Linked items element limited to a single type with at most or exactly 1 item. diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs index 5083cc1e..dd6820af 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs @@ -62,6 +62,24 @@ public void GenerateCommentString_Returns() var result = TextHelpers.GenerateCommentString(customComment); Assert.Equal(expectedComment, result); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void GetEnumerableType_TypeNameIsNullOrWhitespace_Throws(string typeName) + { + Assert.Throws(() => TextHelpers.GetEnumerableType(typeName)); + } + + [Fact] + public void GetEnumerableType_Returns() + { + var typeName = "Hero"; + + var result = TextHelpers.GetEnumerableType(typeName); + Assert.Equal("IEnumerable", result); } } From 6f5f58a72cb0492b8a5079a944d1b4f9bd27802b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 11 Nov 2022 00:03:47 +0100 Subject: [PATCH 24/48] 90 ExtendedDeliveryCodeGenerator impl + tests --- .../ExtendedDeliveryCodeGenerator.cs | 102 ++++- .../ExtendedDeliveryCodeGeneratorTests.cs | 382 ++++++++++++++++++ .../Kontent.Ai.ModelGenerator.Tests.csproj | 1 + 3 files changed, 481 insertions(+), 4 deletions(-) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs index b8c8eeec..16e4c160 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs @@ -2,27 +2,121 @@ using System.Collections.Generic; using System.Threading.Tasks; using Kontent.Ai.Management; +using Kontent.Ai.Management.Extensions; using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.Management.Models.TypeSnippets; +using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Kontent.Ai.ModelGenerator.Core.Helpers; using Microsoft.Extensions.Options; namespace Kontent.Ai.ModelGenerator.Core; public class ExtendedDeliveryCodeGenerator : DeliveryCodeGeneratorBase { + public const string TypedSuffixFileName = ".Typed"; + private readonly IManagementClient _managementClient; + public ExtendedDeliveryCodeGenerator(IOptions options, IOutputProvider outputProvider, IManagementClient managementClient) : base(options, outputProvider) { + if (options.Value.ManagementApi()) + { + throw new InvalidOperationException("Cannot create Extended Delivery models with Management API enabled."); + } + + if (!options.Value.ExtendedDeliveryModels()) + { + throw new InvalidOperationException("Cannot create Extended Delivery models."); + } + + _managementClient = managementClient; + } + + protected override async Task> GetClassCodeGenerators() + { + var deliveryTypes = await _managementClient.ListContentTypesAsync().GetAllAsync(); + var managementSnippets = await _managementClient.ListContentTypeSnippetsAsync().GetAllAsync(); + + var codeGenerators = new List(); + if (deliveryTypes == null) + { + return codeGenerators; + } + + codeGenerators.Add(new ContentItemClassCodeGenerator(Options.Namespace)); + + foreach (var contentType in deliveryTypes) + { + try + { + if (Options.GeneratePartials) + { + codeGenerators.Add(GetCustomClassCodeGenerator(contentType.Codename)); + } + + codeGenerators.AddRange(GetClassCodeGenerators(contentType, managementSnippets, deliveryTypes)); + } + catch (InvalidIdentifierException) + { + WriteConsoleErrorMessage(contentType.Codename); + } + } + + return codeGenerators; } - protected override Task> GetClassCodeGenerators() + internal IEnumerable GetClassCodeGenerators(ContentTypeModel contentType, List managementSnippets, List contentTypes) { - throw new NotImplementedException(); + var classDefinition = new ClassDefinition(contentType.Codename); + var typedClassDefinition = new ClassDefinition(contentType.Codename); + + foreach (var element in contentType.Elements) + { + try + { + if (element.Type != ElementMetadataType.ContentTypeSnippet) + { + AddProperty(element, ref classDefinition, ref typedClassDefinition, contentTypes); + } + else + { + var snippetElements = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, managementSnippets); + foreach (var snippetElement in snippetElements) + { + AddProperty(snippetElement, ref classDefinition, ref typedClassDefinition, contentTypes); + } + } + } + catch (Exception e) + { + WriteConsoleErrorMessage(e, element.Codename, element.Type.ToString(), classDefinition.ClassName); + } + } + + return new List + { + new TypedExtendedDeliveryClassCodeGenerator(typedClassDefinition, GetFileClassName(classDefinition.ClassName + TypedSuffixFileName)), + ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, GetFileClassName(classDefinition.ClassName)) + }; } - internal IEnumerable GetClassCodeGenerator(ContentTypeModel contentType, List managementSnippets, List contentTypes) + private void AddProperty(ElementMetadataBase el, ref ClassDefinition classDefinition, ref ClassDefinition typedClassDefinition, List contentTypes) { - throw new NotImplementedException(); + var elementType = DeliveryElementHelper.GetElementType(Options, el.Type.ToString()); + if (elementType == ElementMetadataType.LinkedItems.ToString()) + { + if (TypedDeliveryPropertyMapper.TryMap(el, contentTypes, Options, out var typedProperty)) + { + AddProperty(typedProperty, ref typedClassDefinition); + } + + elementType = TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName); + } + + var property = Property.FromContentTypeElement(el, elementType!); + + AddProperty(property, ref classDefinition); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs new file mode 100644 index 00000000..35995ad6 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -0,0 +1,382 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using Kontent.Ai.Management; +using Kontent.Ai.Management.Configuration; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.Types.Elements; +using Kontent.Ai.Management.Models.TypeSnippets; +using Kontent.Ai.ModelGenerator.Core; +using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.ModelGenerator.Core.Configuration; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; +using Kontent.Ai.ModelGenerator.Core.Helpers; +using Kontent.Ai.ModelGenerator.Tests.TestHelpers; +using Microsoft.Extensions.Options; +using Moq; +using Xunit; + +namespace Kontent.Ai.ModelGenerator.Tests; + +public class ExtendedDeliveryCodeGeneratorTests : CodeGeneratorTestsBase +{ + /// + /// represents count of elements in 'management_types.json' + /// + private const int NumberOfContentTypesWithDefaultContentItem = (14 * 2) + 1; + + private readonly string DefaultLinkedItemsType = TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName); + private readonly IManagementClient _managementClient; + private readonly IOutputProvider _outputProvider; + protected override string TempDir => Path.Combine(Path.GetTempPath(), "ExtendedDeliveryCodeGeneratorIntegrationTests"); + + public ExtendedDeliveryCodeGeneratorTests() + { + _managementClient = CreateManagementClient(); + _outputProvider = new Mock().Object; + } + + [Fact] + public void Constructor_ManagementIsTrue_Throws() + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = true + }); + + Creator(mockOptions.Object).Should().Throw(); + } + + [Fact] + public void Constructor_ExtendedDeliverModelsIsFalse_Throws() + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = false + }); + + Creator(mockOptions.Object).Should().Throw(); + } + + [Theory] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(true, true)] + public void Constructor_CreatesInstance(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = extendedDeliverModels, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }); + + var extendedDeliveryCodeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); + + extendedDeliveryCodeGenerator.Should().NotBeNull(); + } + + [Fact] + public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = true, + ExtendedDeliverPreviewModels = false + }); + + var contentType = new ContentTypeModel + { + Codename = "content_type", + Elements = new List + { + LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, + LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, + LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, + LinkedItemsContentTypeData.MultiAllowedTypesMultiItems + } + }; + + var contentTypes = new List { contentType, LinkedItemsContentTypeData.ArticleContentType, LinkedItemsContentTypeData.HeroContentType }; + + var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); + + var result = codeGenerator.GetClassCodeGenerators(contentType, new List(), contentTypes).ToList(); + + var expectedTypedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); + expectedTypedExtendedDeliveryClassDefinition.Properties.AddRange(new List + { + Property.FromContentTypeElement( + LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, + $"IEnumerable<{LinkedItemsContentTypeData.HeroContentType.Name}>", + "ModularContentHeroes_Hero"), + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, LinkedItemsContentTypeData.ArticleContentType.Name) + }); + expectedTypedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List + { + "ModularContentHeroes_Hero", + "modular_content_article" + }); + + var expectedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); + expectedExtendedDeliveryClassDefinition.Properties.AddRange(new List + { + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType) + }); + expectedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List + { + "modular_content_heroes", + "modular_content_article", + "modular_content_blog", + "modular_content_coffees" + }); + + var expected = new List + { + new TypedExtendedDeliveryClassCodeGenerator(expectedTypedExtendedDeliveryClassDefinition, "ContentType.Typed.Generated"), + new ExtendedDeliveryClassCodeGenerator(expectedExtendedDeliveryClassDefinition, "ContentType.Generated") + }; + + result.Should().BeEquivalentTo(expected); + } + + [Fact] + public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsTrue_Returns() + { + var mockOptions = new Mock>(); + mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + ExtendedDeliverPreviewModels = true + }); + + var contentType = new ContentTypeModel + { + Codename = "content_type", + Elements = new List + { + LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, + LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, + LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, + LinkedItemsContentTypeData.MultiAllowedTypesMultiItems + } + }; + + var contentTypes = new List { contentType, LinkedItemsContentTypeData.ArticleContentType, LinkedItemsContentTypeData.HeroContentType }; + + var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); + + var result = codeGenerator.GetClassCodeGenerators(contentType, new List(), contentTypes).ToList(); + + var expectedTypedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); + expectedTypedExtendedDeliveryClassDefinition.Properties.AddRange(new List + { + Property.FromContentTypeElement( + LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, + $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", + "ModularContentHeroes_Hero"), + Property.FromContentTypeElement( + LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, + $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", + "modular_content_article") + }); + expectedTypedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List + { + "ModularContentHeroes_Hero", + "modular_content_article" + }); + + var expectedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); + expectedExtendedDeliveryClassDefinition.Properties.AddRange(new List + { + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType) + }); + expectedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List + { + "modular_content_heroes", + "modular_content_article", + "modular_content_blog", + "modular_content_coffees" + }); + + var expected = new List + { + new TypedExtendedDeliveryClassCodeGenerator(expectedTypedExtendedDeliveryClassDefinition, "ContentType.Typed.Generated"), + new ExtendedDeliveryClassCodeGenerator(expectedExtendedDeliveryClassDefinition, "ContentType.Generated") + }; + + result.Should().BeEquivalentTo(expected); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task IntegrationTest_RunAsync_CorrectFiles(bool extendedDeliverPreviewModels) + { + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + ExtendedDeliverModels = true, + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = false, + GeneratePartials = false, + WithTypeProvider = false, + StructuredModel = false, + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }); + + var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + + await codeGenerator.RunAsync(); + + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem); + + Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs").Should().NotBeEmpty(); + Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs")).Should().NotBeEmpty(); + + // Cleanup + Directory.Delete(TempDir, true); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(bool extendedDeliverPreviewModels) + { + const string transformFilename = "CustomSuffix"; + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + ExtendedDeliverModels = true, + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = false, + GeneratePartials = false, + WithTypeProvider = false, + StructuredModel = false, + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, + FileNameSuffix = transformFilename, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }); + + var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + + await codeGenerator.RunAsync(); + + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem); + + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(f => !f.Contains($"{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs"))) + { + Path.GetFileName(filepath).Should().EndWith($".{transformFilename}.cs"); + } + + // Cleanup + Directory.Delete(TempDir, true); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(bool extendedDeliverPreviewModels) + { + const string transformFilename = "Generated"; + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + ExtendedDeliverModels = true, + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = false, + GeneratePartials = true, + WithTypeProvider = false, + StructuredModel = false, + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, + FileNameSuffix = transformFilename, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }); + + var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + + await codeGenerator.RunAsync(); + + var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; + var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; + var result = generatedCount + (generatedCount / 2) + 1; + + result.Should().Be(allFilesCount); + + var defaultContentItemClassCodeGeneratorExists = File.Exists(Path.GetFullPath($"{TempDir}//{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs")); + defaultContentItemClassCodeGeneratorExists.Should().BeTrue(); + + + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir)) + .Where(f => + !f.Contains($"{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs") && + !f.Contains($".{transformFilename}.cs") && + !f.Contains($"{ExtendedDeliveryCodeGenerator.TypedSuffixFileName}.{transformFilename}.cs"))) + { + var generatedFileExists = File.Exists(filepath.Replace(".cs", $".{transformFilename}.cs")); + var typedGeneratedFileExists = File.Exists(filepath.Replace(".cs", $"{ExtendedDeliveryCodeGenerator.TypedSuffixFileName}.{transformFilename}.cs")); + + generatedFileExists.Should().BeTrue(); + typedGeneratedFileExists.Should().BeTrue(); + } + + // Cleanup + Directory.Delete(TempDir, true); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(bool extendedDeliverPreviewModels) + { + var mockOptions = new Mock>(); + mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions + { + ExtendedDeliverModels = true, + Namespace = "CustomNamespace", + OutputDir = TempDir, + ManagementApi = false, + GeneratePartials = false, + WithTypeProvider = true, + StructuredModel = false, + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, + ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + }); + + var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); + + await codeGenerator.RunAsync(); + + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem + 1); + + Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs").Should().NotBeEmpty(); + + // Cleanup + Directory.Delete(TempDir, true); + } + + private Func Creator(IOptions options) => + () => new ExtendedDeliveryCodeGenerator(options, _outputProvider, _managementClient); +} \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj index 7486232a..61f117c2 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj +++ b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj @@ -59,6 +59,7 @@ + From da544d9e9fc6e0177752a96174e6859f1b83c6bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 5 Jan 2023 14:25:53 +0100 Subject: [PATCH 25/48] 90 use fluentAssertions --- .../Generators/Class/ClassCodeGeneratorTestsBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs index ea34b1cc..867ffe4d 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ClassCodeGeneratorTestsBase.cs @@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis; using System.IO; using System.Linq; -using Xunit; +using FluentAssertions; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -29,6 +29,6 @@ protected void AssertCompiledCode(CSharpCompilation compilation) } } - Assert.True(result.Success, compilationErrors); + result.Success.Should().BeTrue(compilationErrors); } } From dd0ad0e05ce1ca4aa43f0df05501d4a439899680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 5 Jan 2023 15:19:51 +0100 Subject: [PATCH 26/48] 90 refactorings --- .../Common/Property.cs | 38 +++----- .../DeliveryCodeGenerator.cs | 23 ----- .../Class/ContentItemClassCodeGenerator.cs | 7 +- .../Class/ManagementClassCodeGenerator.cs | 2 +- ...TypedExtendedDeliveryClassCodeGenerator.cs | 12 +-- .../Helpers/TextHelpers.cs | 28 ++---- .../Helpers/TypedDeliveryPropertyMapper.cs | 1 - .../Options/ArgMappingsRegister.cs | 2 +- .../ArgHelpersTests.cs | 40 ++++---- .../Common/ClassCodeGeneratorFactoryTests.cs | 27 ++++-- .../Common/PropertyTests.cs | 33 ++++--- .../CodeGeneratorOptionsExtensionsTests.cs | 33 +++---- .../DeliveryCodeGeneratorTests.cs | 30 +++--- .../FileSystemOutputProviderTests.cs | 13 ++- .../Class/BaseClassCodeGeneratorTests.cs | 7 +- .../ContentItemClassCodeGeneratorTests.cs | 7 +- .../Class/DeliveryClassCodeGeneratorTests.cs | 7 +- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 7 +- .../ManagementClassCodeGeneratorTests.cs | 7 +- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 7 +- .../Helpers/ManagementElementHelperTests.cs | 36 +++++--- .../Helpers/TextHelpersTests.cs | 24 +++-- .../TypedDeliveryPropertyMapperTests.cs | 92 +++++++++++-------- .../ManagementCodeGeneratorTests.cs | 46 +++------- .../UsedSdkInfoTests.cs | 16 ++-- .../ValidationExtensionsTests.cs | 47 +++++++--- 26 files changed, 300 insertions(+), 292 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 806ef101..0cc86602 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -75,32 +75,18 @@ public Property(string codename, string typeName, string id = null) Id = id; } - public static bool IsContentTypeSupported(string elementType, bool extendedDeliverModels) - { - return extendedDeliverModels - ? ExtendedDeliverElementTypesDictionary.ContainsKey(elementType) - : DeliverElementTypesDictionary.ContainsKey(elementType); - } + public static bool IsContentTypeSupported(string elementType, bool extendedDeliverModels) => extendedDeliverModels + ? ExtendedDeliverElementTypesDictionary.ContainsKey(elementType) + : DeliverElementTypesDictionary.ContainsKey(elementType); - public static bool IsContentTypeSupported(string elementType) - { - return DeliverElementTypesDictionary.ContainsKey(elementType); - } + public static bool IsContentTypeSupported(string elementType) => DeliverElementTypesDictionary.ContainsKey(elementType); - public static bool IsContentTypeSupported(ElementMetadataType elementType) - { - return ManagementElementTypesDictionary.ContainsKey(elementType); - } + public static bool IsContentTypeSupported(ElementMetadataType elementType) => + ManagementElementTypesDictionary.ContainsKey(elementType); - public static Property FromContentTypeElement(string codename, string elementType) - { - if (IsContentTypeSupported(elementType)) - { - return new Property(codename, DeliverElementTypesDictionary[elementType]); - } - - throw new ArgumentException($"Unknown Content Type {elementType}", nameof(elementType)); - } + public static Property FromContentTypeElement(string codename, string elementType) => IsContentTypeSupported(elementType) + ? new Property(codename, DeliverElementTypesDictionary[elementType]) + : throw new ArgumentException($"Unknown Content Type {elementType}", nameof(elementType)); public static Property FromContentTypeElement(ElementMetadataBase element) { @@ -117,10 +103,8 @@ public static Property FromContentTypeElement(ElementMetadataBase element) throw new ArgumentException($"Unknown Content Type {element.Type}", nameof(element)); } - public static Property FromContentTypeElement(ElementMetadataBase element, string elementType) - { - return FromContentTypeElement(element, elementType, element.Codename); - } + public static Property FromContentTypeElement(ElementMetadataBase element, string elementType) => + FromContentTypeElement(element, elementType, element.Codename); public static Property FromContentTypeElement(ElementMetadataBase element, string elementType, string finalPropertyName) { diff --git a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs index b23412df..2f543bca 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGenerator.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Configuration; -using Kontent.Ai.ModelGenerator.Core.Generators; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Kontent.Ai.ModelGenerator.Core.Helpers; using Microsoft.Extensions.Options; @@ -82,27 +80,6 @@ internal ClassCodeGenerator GetClassCodeGenerator(IContentType contentType) return ClassCodeGeneratorFactory.CreateClassCodeGenerator(Options, classDefinition, classFilename); } - private async Task GenerateTypeProvider() - { - var classCodeGenerators = await GetClassCodeGenerators(); - - if (!classCodeGenerators.Any()) - { - Console.WriteLine(NoContentTypeAvailableMessage); - return; - } - - var typeProviderCodeGenerator = new TypeProviderCodeGenerator(Options.Namespace); - - foreach (var codeGenerator in classCodeGenerators) - { - typeProviderCodeGenerator.AddContentType(codeGenerator.ClassDefinition.Codename, codeGenerator.ClassDefinition.ClassName); - } - - var typeProviderCode = typeProviderCodeGenerator.GenerateCode(); - WriteToOutputProvider(typeProviderCode, TypeProviderCodeGenerator.ClassName, true); - } - private static void TryAddSystemProperty(ClassDefinition classDefinition) { try diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs index ffe43507..0565131b 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs @@ -11,12 +11,7 @@ public class ContentItemClassCodeGenerator : ClassCodeGenerator public const string DefaultContentItemClassName = "IContentItem"; public ContentItemClassCodeGenerator(string @namespace = DefaultNamespace) - : this(new ClassDefinition(DefaultContentItemClassName), DefaultContentItemClassName, @namespace) - { - } - - private ContentItemClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) - : base(classDefinition, classFilename, @namespace) + : base(new ClassDefinition(DefaultContentItemClassName), DefaultContentItemClassName, @namespace) { } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs index cebfd038..7261682e 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ManagementClassCodeGenerator.cs @@ -38,7 +38,7 @@ protected override TypeDeclarationSyntax GetClassDeclaration() return classDeclaration; } - private MemberDeclarationSyntax[] Properties => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => + protected override MemberDeclarationSyntax[] Properties => ClassDefinition.Properties.OrderBy(p => p.Identifier).Select(element => SyntaxFactory .PropertyDeclaration(SyntaxFactory.ParseTypeName(element.TypeName), element.Identifier) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs index fad95e8b..6200d778 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/TypedExtendedDeliveryClassCodeGenerator.cs @@ -85,13 +85,7 @@ private MemberDeclarationSyntax[] GetProperties() private static string GetNonEnumerableTypeName(string typeName) => Regex.Match(typeName, "[^\\>|\\<]\\w+\\b(? propertyName == typeName + ? typeName + : propertyName.Substring(0, propertyName.Length - typeName.Length); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs index 3b26716f..29aa563f 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs @@ -16,7 +16,7 @@ public static class TextHelpers ///
public static string GetValidPascalCaseIdentifierName(string name) { - string sanitizedName = Regex.Replace(name, "[^a-zA-Z0-9]", WordSeparator, RegexOptions.IgnoreCase | RegexOptions.Multiline); + var sanitizedName = Regex.Replace(name, "[^a-zA-Z0-9]", WordSeparator, RegexOptions.IgnoreCase | RegexOptions.Multiline); // Remove leading numbers and leading whitespace (e.g.: ' 123Name123' -> 'Name123' sanitizedName = Regex.Replace(sanitizedName, "^(\\s|[0-9])+", ""); @@ -27,16 +27,14 @@ public static string GetValidPascalCaseIdentifierName(string name) } return sanitizedName - .ToLower() - .Split(new[] { WordSeparator }, StringSplitOptions.RemoveEmptyEntries) - .Select(word => char.ToUpper(word[0]) + word.Substring(1)) - .Aggregate((previous, current) => previous + current); + .ToLower() + .Split(new[] { WordSeparator }, StringSplitOptions.RemoveEmptyEntries) + .Select(word => char.ToUpper(word[0]) + word.Substring(1)) + .Aggregate((previous, current) => previous + current); } - public static string NormalizeLineEndings(this string text) - { - return LineEndings.Replace(text, Environment.NewLine); - } + public static string NormalizeLineEndings(this string text) => + LineEndings.Replace(text, Environment.NewLine); public static string GenerateCommentString(string customComment) { @@ -54,13 +52,7 @@ public static string GenerateCommentString(string customComment) //
{Environment.NewLine}{Environment.NewLine}"; } - public static string GetEnumerableType(string typeName) - { - if (string.IsNullOrWhiteSpace(typeName)) - { - throw new ArgumentException("", nameof(typeName)); - } - - return $"{nameof(IEnumerable)}<{typeName}>"; - } + public static string GetEnumerableType(string typeName) => string.IsNullOrWhiteSpace(typeName) + ? throw new ArgumentException("", nameof(typeName)) + : $"{nameof(IEnumerable)}<{typeName}>"; } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index d23fe4d6..4212a872 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -4,7 +4,6 @@ using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using Kontent.Ai.Management.Extensions; diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs index f577b177..6ceb5f07 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs @@ -51,4 +51,4 @@ internal class ArgMappingsRegister .Union(DeliveryMappings.Keys) .Union(ManagementMappings.Keys) .Union(ExtendedDeliveryMappings.Keys); -} \ No newline at end of file +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index 80f38175..7039ff5e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using FluentAssertions; using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; @@ -74,7 +75,7 @@ public void GetSwitchMappings_MissingMapiSwitch_ReturnsDeliveryMappings() Guid.NewGuid().ToString() }); - Assert.Equal(ExpectedDeliveryMappings, result); + result.Should().BeEquivalentTo(ExpectedDeliveryMappings); } [Fact] @@ -88,7 +89,7 @@ public void GetSwitchMappings_MapiSwitchIsFalse_ReturnsDeliveryMappings() "false" }); - Assert.Equal(ExpectedDeliveryMappings, result); + result.Should().BeEquivalentTo(ExpectedDeliveryMappings); } [Fact] @@ -102,7 +103,7 @@ public void GetSwitchMappings_MapiSwitchIsTrue_ReturnsManagementMappings() "true" }); - Assert.Equal(ExpectedManagementMappings, result); + result.Should().BeEquivalentTo(ExpectedManagementMappings); } [Fact] @@ -116,7 +117,7 @@ public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() "true" }); - Assert.Equal(ExpectedExtendedDeliveryMappings, result); + result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); } [Fact] @@ -130,7 +131,7 @@ public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMap "true" }); - Assert.Equal(ExpectedExtendedDeliveryMappings, result); + result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); } [Fact] @@ -146,7 +147,7 @@ public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagement "true" }); - Assert.Equal(ExpectedExtendedDeliveryMappings, result); + result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); } [Fact] @@ -164,7 +165,7 @@ public void ContainsContainsValidArgs_SupportedDeliveryOptions_ReturnsTrue() var result = ArgHelpers.ContainsValidArgs(args); - Assert.True(result); + result.Should().BeTrue(); } [Theory] @@ -181,7 +182,7 @@ public void ContainsContainsValidArgs_UnsupportedDeliveryOptions_ReturnsFalse(st }; var result = ArgHelpers.ContainsValidArgs(args); - Assert.False(result); + result.Should().BeFalse(); } [Fact] @@ -198,7 +199,7 @@ public void ContainsContainsValidArgs_SupportedManagementOptions_ReturnsTrue() var result = ArgHelpers.ContainsValidArgs(args); - Assert.True(result); + result.Should().BeTrue(); } [Theory] @@ -216,7 +217,7 @@ public void ContainsContainsValidArgs_UnsupportedManagementOptions_ReturnsFalse( }; var result = ArgHelpers.ContainsValidArgs(args); - Assert.False(result); + result.Should().BeFalse(); } [Fact] @@ -234,7 +235,7 @@ public void ContainsContainsValidArgs_SupportedExtendedDeliveryOptions_ReturnsTr var result = ArgHelpers.ContainsValidArgs(args); - Assert.True(result); + result.Should().BeTrue(); } [Theory] @@ -255,7 +256,7 @@ public void ContainsContainsValidArgs_UnsupportedExtendedDeliveryOptions_Returns var result = ArgHelpers.ContainsValidArgs(args); - Assert.False(result); + result.Should().BeFalse(); } [Fact] @@ -263,8 +264,7 @@ public void GetProgramOptionsData_ManagementApi_ReturnsManagementProgramOptionsD { var result = ArgHelpers.GetUsedSdkInfo(DesiredModelsType.Management); - Assert.Equal("management-sdk-net", result.Name); - Assert.Equal(Assembly.GetAssembly(typeof(ManagementOptions)).GetName().Version.ToString(3), result.Version); + AssertUsedSdkInfoResult(result, "management-sdk-net", typeof(ManagementOptions)); } [Fact] @@ -272,8 +272,7 @@ public void GetProgramOptionsData_DeliveryApi_ReturnsDeliveryProgramOptionsData( { var result = ArgHelpers.GetUsedSdkInfo(DesiredModelsType.Delivery); - Assert.Equal("delivery-sdk-net", result.Name); - Assert.Equal(Assembly.GetAssembly(typeof(DeliveryOptions)).GetName().Version.ToString(3), result.Version); + AssertUsedSdkInfoResult(result, "delivery-sdk-net", typeof(DeliveryOptions)); } [Fact] @@ -281,8 +280,7 @@ public void GetProgramOptionsData_ExtendedDeliveryApi_ReturnsExtendedDeliveryPro { var result = ArgHelpers.GetUsedSdkInfo(DesiredModelsType.ExtendedDelivery); - Assert.Equal("delivery-sdk-net", result.Name); - Assert.Equal(Assembly.GetAssembly(typeof(DeliveryOptions)).GetName().Version.ToString(3), result.Version); + AssertUsedSdkInfoResult(result, "delivery-sdk-net", typeof(DeliveryOptions)); } private static IEnumerable AppendValuesToArgs(IDictionary mappings) => AppendValuesToArgs(mappings.Keys); @@ -302,4 +300,10 @@ private static IEnumerable AppendValuesToArgs(IEnumerable args) } return argsWithValue; } + + private static void AssertUsedSdkInfoResult(UsedSdkInfo result, string expectedName, Type expectedType) + { + result.Name.Should().Be(expectedName); + result.Version.Should().Be(Assembly.GetAssembly(expectedType).GetName().Version.ToString(3)); + } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs index bbfffe7c..c601c803 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs @@ -1,4 +1,5 @@ using System; +using FluentAssertions; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Generators.Class; @@ -11,22 +12,28 @@ public class ClassCodeGeneratorFactoryTests [Fact] public void CreateClassCodeGenerator_CodeGeneratorOptionsIsNull_ThrowsException() { - Assert.Throws(() => - ClassCodeGeneratorFactory.CreateClassCodeGenerator(null, new ClassDefinition("codename"), "classFileName")); + var createClassCodeGeneratorCall = () => + ClassCodeGeneratorFactory.CreateClassCodeGenerator(null, new ClassDefinition("codename"), "classFileName"); + + createClassCodeGeneratorCall.Should().ThrowExactly(); } [Fact] public void CreateClassCodeGenerator_ClassDefinitionIsNull_ThrowsException() { - Assert.Throws(() => - ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), null, "classFileName")); + var createClassCodeGeneratorCall = () => + ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), null, "classFileName"); + + createClassCodeGeneratorCall.Should().ThrowExactly(); } [Fact] public void CreateClassCodeGenerator_ClassFilenameIsNull_ThrowsException() { - Assert.Throws(() => - ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), new ClassDefinition("codename"), null)); + var createClassCodeGeneratorCall = () => + ClassCodeGeneratorFactory.CreateClassCodeGenerator(new CodeGeneratorOptions(), new ClassDefinition("codename"), null); + + createClassCodeGeneratorCall.Should().ThrowExactly(); } [Fact] @@ -184,9 +191,9 @@ public void CreateClassCodeGenerator_ManagementClassCodeGenerator_CustomNamespac private static void AssertClassCodeGenerator(ClassCodeGenerator result, string classDefinitionCodename, string classFileName, string @namespace) { - Assert.IsType(result); - Assert.Equal(classDefinitionCodename, result.ClassDefinition.Codename); - Assert.Equal(classFileName, result.ClassFilename); - Assert.Equal(@namespace, result.Namespace); + result.Should().BeOfType(); + result.ClassDefinition.Codename.Should().Be(classDefinitionCodename); + result.ClassFilename.Should().Be(classFileName); + result.Namespace.Should().Be(@namespace, result.Namespace); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs index 841d6fa8..033912ce 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using FluentAssertions; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Tests.TestHelpers; @@ -15,9 +16,9 @@ public void Constructor_MissingIdParam_ObjectIsInitializedWithCorrectValues() { var element = new Property("element_codename", "string"); - Assert.Equal("ElementCodename", element.Identifier); - Assert.Equal("string", element.TypeName); - Assert.Null(element.Id); + element.Identifier.Should().Be("ElementCodename"); + element.TypeName.Should().Be("string"); + element.Id.Should().BeNull(); } [Theory] @@ -28,9 +29,9 @@ public void Constructor_IdParamPresent_ObjectIsInitializedWithCorrectValues(stri { var element = new Property("element_codename", "string", id); - Assert.Equal("ElementCodename", element.Identifier); - Assert.Equal("string", element.TypeName); - Assert.Equal(id, element.Id); + element.Identifier.Should().Be("ElementCodename"); + element.TypeName.Should().Be("string"); + element.Id.Should().Be(id); } [Theory] @@ -52,8 +53,8 @@ public void FromContentTypeElement_DeliveryApiModel_Returns(string contentType, var element = Property.FromContentTypeElement(codename, contentType); - Assert.Equal(expectedCodename, element.Identifier); - Assert.Equal(expectedTypeName, element.TypeName); + element.Identifier.Should().Be(expectedCodename); + element.TypeName.Should().Be(expectedTypeName); } [Theory, MemberData(nameof(ManagementElements))] @@ -61,22 +62,26 @@ public void FromContentTypeElement_ManagementApiModel_Returns(string expectedTyp { var property = Property.FromContentTypeElement(element); - Assert.Equal(expectedCodename, property.Identifier); - Assert.Equal(expectedTypeName, property.TypeName); - Assert.Equal(element.Id.ToString(), property.Id); + property.Identifier.Should().Be(expectedCodename); + property.TypeName.Should().Be(expectedTypeName); + property.Id.Should().Be(element.Id.ToString()); } [Fact] public void FromContentTypeElement_DeliveryApiModel_InvalidContentTypeElement_Throws() { - Assert.Throws(() => Property.FromContentTypeElement("codename", "unknown content type")); + var fromContentTypeElementCall = () => Property.FromContentTypeElement("codename", "unknown content type"); + + fromContentTypeElementCall.Should().ThrowExactly(); } [Fact] public void FromContentTypeElement_ManagementApiModel_GuidelinesElement_Throws() { - Assert.Throws(() => - Property.FromContentTypeElement(TestDataGenerator.GenerateGuidelinesElement(Guid.NewGuid(), "codename"))); + var fromContentTypeElementCall = () => + Property.FromContentTypeElement(TestDataGenerator.GenerateGuidelinesElement(Guid.NewGuid(), "codename")); + + fromContentTypeElementCall.Should().ThrowExactly(); } public static IEnumerable ManagementElements => diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index 0444acc6..269fad38 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -1,4 +1,5 @@ -using Kontent.Ai.ModelGenerator.Core.Configuration; +using FluentAssertions; +using Kontent.Ai.ModelGenerator.Core.Configuration; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests.Configuration; @@ -17,7 +18,7 @@ public void ManagementApi_ManagementApi_ReturnsTrue() var result = options.ManagementApi(); - Assert.True(result); + result.Should().BeTrue(); } [Theory] @@ -36,7 +37,7 @@ public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverMode var result = options.ManagementApi(); - Assert.False(result); + result.Should().BeFalse(); } [Theory] @@ -54,7 +55,7 @@ public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, var result = options.ManagementApi(); - Assert.False(result); + result.Should().BeFalse(); } [Theory] @@ -73,7 +74,7 @@ public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extende var result = options.ExtendedDeliveryModels(); - Assert.False(result); + result.Should().BeFalse(); } [Fact] @@ -88,7 +89,7 @@ public void ExtendedDeliveryModels_ManagementApiIsFalse_ExtendedDeliveryOptionsA var result = options.ExtendedDeliveryModels(); - Assert.False(result); + result.Should().BeFalse(); } [Theory] @@ -106,7 +107,7 @@ public void ExtendedDeliveryModels_ManagementApiIsFalse_ReturnsTrue(bool extende var result = options.ExtendedDeliveryModels(); - Assert.True(result); + result.Should().BeTrue(); } [Fact] @@ -116,7 +117,7 @@ public void DeliveryApi_DefaultOptions_ReturnsTrue() var result = options.DeliveryApi(); - Assert.True(result); + result.Should().BeTrue(); } [Fact] @@ -131,7 +132,7 @@ public void DeliveryApi_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_Ret var result = options.DeliveryApi(); - Assert.True(result); + result.Should().BeTrue(); } [Fact] @@ -146,7 +147,7 @@ public void DeliveryApi_ManagementApi_ReturnsFalse() var result = options.DeliveryApi(); - Assert.False(result); + result.Should().BeFalse(); } [Theory] @@ -164,7 +165,7 @@ public void DeliveryApi_ExtendedDeliveryOptions_ReturnsFalse(bool extendedDelive var result = options.DeliveryApi(); - Assert.False(result); + result.Should().BeFalse(); } [Fact] @@ -179,7 +180,7 @@ public void DeliveryApi_ManagementApiIsTrue_ExtendedDeliveryOptionsAreTrue_Retur var result = options.DeliveryApi(); - Assert.True(result); + result.Should().BeTrue(); } [Fact] @@ -194,7 +195,7 @@ public void GetDesiredModelsType_ManagementApi_ReturnsManagement() var result = options.GetDesiredModelsType(); - Assert.Equal(DesiredModelsType.Management, result); + result.Should().Be(DesiredModelsType.Management); } [Theory] @@ -212,7 +213,7 @@ public void GetDesiredModelsType_ExtendedDeliveryModels_ReturnsExtendedDelivery( var result = options.GetDesiredModelsType(); - Assert.Equal(DesiredModelsType.ExtendedDelivery, result); + result.Should().Be(DesiredModelsType.ExtendedDelivery); } [Fact] @@ -227,7 +228,7 @@ public void GetDesiredModelsType_ManagementApiIsFalse_ExtendedDeliveryOptionsAre var result = options.GetDesiredModelsType(); - Assert.Equal(DesiredModelsType.Delivery, result); + result.Should().Be(DesiredModelsType.Delivery); } [Fact] @@ -237,6 +238,6 @@ public void GetDesiredModelsType_DefaultOptions_ReturnsDelivery() var result = options.GetDesiredModelsType(); - Assert.Equal(DesiredModelsType.Delivery, result); + result.Should().Be(DesiredModelsType.Delivery); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs index a04461c5..110d0273 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using FluentAssertions; using Kontent.Ai.Delivery; using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Delivery.Builders.DeliveryClient; @@ -35,7 +36,9 @@ public void Constructor_ManagementIsTrue_Throws() var deliveryClient = new Mock(); var outputProvider = new Mock(); - Assert.Throws(() => new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object)); + var call = () => new DeliveryCodeGenerator(mockOptions.Object, outputProvider.Object, deliveryClient.Object); + + call.Should().ThrowExactly(); } [Theory] @@ -67,7 +70,7 @@ public void GetClassCodeGenerator_Returns(bool structuredModel) var result = codeGenerator.GetClassCodeGenerator(contentType.Object); - Assert.Equal($"{contentTypeCodename}.Generated", result.ClassFilename); + result.ClassFilename.Should().Be($"{contentTypeCodename}.Generated"); } [Fact] @@ -96,11 +99,11 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() await codeGenerator.RunAsync(); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypes); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs")); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs"))); - Assert.Empty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs")); + Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs").Should().NotBeEmpty(); + Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs")).Should().NotBeEmpty(); + Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs").Should().BeEmpty(); // Cleanup Directory.Delete(TempDir, true); @@ -135,11 +138,11 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() await codeGenerator.RunAsync(); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypes); foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) { - Assert.EndsWith($".{transformFilename}.cs", Path.GetFileName(filepath)); + Path.GetFileName(filepath).Should().EndWith($".{transformFilename}.cs"); } // Cleanup @@ -178,12 +181,14 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; - Assert.Equal(allFilesCount, generatedCount * 2); + + var resultGeneratedFilesCount = generatedCount * 2; + resultGeneratedFilesCount.Should().Be(allFilesCount); foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs")) { var customFileExists = File.Exists(filepath.Replace($".{transformFilename}", "")); - Assert.True(customFileExists); + customFileExists.Should().BeTrue(); } // Cleanup @@ -216,9 +221,8 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() await codeGenerator.RunAsync(); - Assert.Equal(NumberOfContentTypes + 1, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); - - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs")); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypes + 1); + Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs").Should().NotBeEmpty(); // Cleanup Directory.Delete(TempDir, true); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs index d03c3d17..0b2cbe2e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/FileSystemOutputProviderTests.cs @@ -3,6 +3,7 @@ using Moq; using System; using System.IO; +using FluentAssertions; using Xunit; namespace Kontent.Ai.ModelGenerator.Tests; @@ -20,14 +21,15 @@ public void CreateCodeGeneratorOptions_NoOutputSetInJsonNorInParameters_OutputDi mockOptions.Setup(x => x.Value).Returns(options); var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Empty(options.OutputDir); - Assert.NotEmpty(outputProvider.OutputDir); + + options.OutputDir.Should().BeEmpty(); + outputProvider.OutputDir.Should().NotBeNullOrEmpty(); } [Fact] public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomValue() { - var expectedOutputDir = Environment.CurrentDirectory; + var expectedOutputDir = Environment.CurrentDirectory.TrimEnd(Path.DirectorySeparatorChar); var mockOptions = new Mock>(); var options = new CodeGeneratorOptions { @@ -36,6 +38,9 @@ public void CreateCodeGeneratorOptions_OutputSetInParameters_OutputDirHasCustomV mockOptions.Setup(x => x.Value).Returns(options); var outputProvider = new FileSystemOutputProvider(mockOptions.Object); - Assert.Equal(expectedOutputDir.TrimEnd(Path.DirectorySeparatorChar), outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar)); + + var result = outputProvider.OutputDir.TrimEnd(Path.DirectorySeparatorChar); + + result.Should().Be(expectedOutputDir); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs index b275a380..85dc96f5 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/BaseClassCodeGeneratorTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using FluentAssertions; using Kontent.Ai.ModelGenerator.Core.Configuration; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Xunit; @@ -23,7 +24,7 @@ public void GenerateBaseClassCodeWithDefaultNamespace() var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); - Assert.Equal(expectedBaseClassCode, actualCompiledBaseClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); + actualCompiledBaseClass.Should().Be(expectedBaseClassCode); } [Fact] @@ -42,7 +43,7 @@ public void GenerateBaseClassCodeWithCustomNamespace() var actualCompiledBaseClass = codeGenerator.GenerateBaseClassCode(); - Assert.Equal(expectedBaseClassCode, actualCompiledBaseClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); + actualCompiledBaseClass.Should().Be(expectedBaseClassCode); } [Fact] @@ -57,6 +58,6 @@ public void GenerateExtenderClassCode() var actualCompiledExtenderClass = codeGenerator.GenerateExtenderCode(); - Assert.Equal(expectedExtenderCode, actualCompiledExtenderClass, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true); + actualCompiledExtenderClass.Should().Be(expectedExtenderCode); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs index 0d7e9fd6..df6d6437 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Reflection; +using FluentAssertions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; @@ -15,8 +16,8 @@ public void Constructor_CreatesInstance() { var classCodeGenerator = new ContentItemClassCodeGenerator(); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); + classCodeGenerator.Should().NotBeNull(); + classCodeGenerator.OverwriteExisting.Should().BeTrue(); } [Fact] @@ -29,7 +30,7 @@ public void Build_CreatesClassWithSystemProperty() var executingPath = AppContext.BaseDirectory; var expectedCode = File.ReadAllText(executingPath + "/Assets/IContentItem_CompiledCode.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + compiledCode.Should().Be(expectedCode); } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs index e088a596..79f62ada 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using FluentAssertions; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Microsoft.CodeAnalysis; @@ -33,8 +34,8 @@ public void Constructor_CreatesInstance() { var classCodeGenerator = new DeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); + classCodeGenerator.Should().NotBeNull(); + classCodeGenerator.OverwriteExisting.Should().BeTrue(); } [Fact] @@ -47,7 +48,7 @@ public void Build_CreatesClassWithCompleteContentType() var executingPath = AppContext.BaseDirectory; var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + compiledCode.Should().Be(expectedCode); } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index d22e5c4c..9eda3ddc 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -11,6 +11,7 @@ using Xunit; using Kontent.Ai.Management.Models.Types; using Kontent.Ai.ModelGenerator.Tests.TestHelpers; +using FluentAssertions; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -102,8 +103,8 @@ public void Constructor_CreatesInstance() { var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); + classCodeGenerator.Should().NotBeNull(); + classCodeGenerator.OverwriteExisting.Should().BeTrue(); } [Fact] @@ -116,7 +117,7 @@ public void Build_CreatesClassWithCompleteContentType() var executingPath = AppContext.BaseDirectory; var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + compiledCode.Should().Be(expectedCode); } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs index 77bad95e..7727185b 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ManagementClassCodeGeneratorTests.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using FluentAssertions; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Generators.Class; @@ -44,8 +45,8 @@ public void Constructor_CreatesInstance() { var classCodeGenerator = new ManagementClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); + classCodeGenerator.Should().NotBeNull(); + classCodeGenerator.OverwriteExisting.Should().BeTrue(); } [Fact] @@ -58,7 +59,7 @@ public void Build_CreatesClassWithCompleteContentType() var executingPath = AppContext.BaseDirectory; var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_ManagementApi.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + compiledCode.Should().Be(expectedCode); } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index be44a148..1a355288 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -12,6 +12,7 @@ using Kontent.Ai.Management.Models.Types; using Kontent.Ai.ModelGenerator.Core.Helpers; using Kontent.Ai.ModelGenerator.Tests.TestHelpers; +using FluentAssertions; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -45,8 +46,8 @@ public void Constructor_CreatesInstance() { var classCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - Assert.NotNull(classCodeGenerator); - Assert.True(classCodeGenerator.OverwriteExisting); + classCodeGenerator.Should().NotBeNull(); + classCodeGenerator.OverwriteExisting.Should().BeTrue(); } [Fact] @@ -59,7 +60,7 @@ public void Build_CreatesClassWithCompleteContentType() var executingPath = AppContext.BaseDirectory; var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt"); - Assert.Equal(expectedCode, compiledCode, ignoreWhiteSpaceDifferences: true, ignoreLineEndingDifferences: true); + compiledCode.Should().Be(expectedCode); } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs index ef8c442f..4dff2dce 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/ManagementElementHelperTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using FluentAssertions; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.Management.Models.TypeSnippets; using Kontent.Ai.ModelGenerator.Core.Helpers; @@ -14,15 +15,19 @@ public class ManagementElementHelperTests [Fact] public void GetManagementContentTypeSnippetElements_ManagementSnippetsAreNull_ThrowsException() { - Assert.Throws(() => - ManagementElementHelper.GetManagementContentTypeSnippetElements(new TextElementMetadataModel(), null)); + var getManagementContentTypeSnippetElementsCall = () => + ManagementElementHelper.GetManagementContentTypeSnippetElements(new TextElementMetadataModel(), null); + + getManagementContentTypeSnippetElementsCall.Should().ThrowExactly(); } [Fact] public void GetManagementContentTypeSnippetElements_ManagementContentTypeIsNull_ThrowsException() { - Assert.Throws(() => - ManagementElementHelper.GetManagementContentTypeSnippetElements(null, new List())); + var getManagementContentTypeSnippetElementsCall = () => + ManagementElementHelper.GetManagementContentTypeSnippetElements(null, new List()); + + getManagementContentTypeSnippetElementsCall.Should().ThrowExactly(); } [Fact] @@ -43,8 +48,8 @@ public void GetManagementContentTypeSnippetElements_NoSnippetElements_Throws() var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets); - Assert.NotNull(result); - Assert.Empty(result); + result.Should().NotBeNull(); + result.Should().BeEmpty(); } [Fact] @@ -54,7 +59,10 @@ public void GetManagementContentTypeSnippetElements_NoSnippets_Throws() var snippetElement = TestDataGenerator.GenerateElementMetadataBase(Guid.NewGuid(), contentTypeElementCodename, ElementMetadataType.ContentTypeSnippet); - Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, new List())); + var getManagementContentTypeSnippetElementsCall = + () => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, new List()); + + getManagementContentTypeSnippetElementsCall.Should().ThrowExactly(); } [Fact] @@ -78,7 +86,9 @@ public void GetManagementContentTypeSnippetElements_NoMatchingSnippet_Throws() } }; - Assert.Throws(() => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets)); + var getManagementContentTypeSnippetElementsCall = () => ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets); + + getManagementContentTypeSnippetElementsCall.Should().ThrowExactly(); } [Fact] @@ -90,7 +100,7 @@ public void GetManagementContentTypeSnippetElements_NotManagementContentTypeSnip var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(element, new List()); - Assert.Null(result); + result.Should().BeNull(); } [Fact] @@ -117,9 +127,9 @@ public void GetManagementContentTypeSnippetElements_Returns() var result = ManagementElementHelper.GetManagementContentTypeSnippetElements(snippetElement, snippets).ToList(); - Assert.NotNull(result); - Assert.Equal(2, result.Count); - Assert.Contains(result, el => el.Id == expectedElementId); - Assert.Contains(result, el => el.Id == expectedElement2Id); + result.Should().NotBeNullOrEmpty(); + result.Count.Should().Be(2); + result.Should().ContainSingle(el => el.Id == expectedElementId); + result.Should().ContainSingle(el => el.Id == expectedElement2Id); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs index dd6820af..ca7d9697 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs @@ -1,4 +1,5 @@ using System; +using FluentAssertions; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Helpers; using Xunit; @@ -10,7 +11,9 @@ public class TextHelpersTests [Fact] public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForNullValue() { - Assert.Throws(() => TextHelpers.GetValidPascalCaseIdentifierName(null)); + var getValidPascalCaseIdentifierNameCall = () => TextHelpers.GetValidPascalCaseIdentifierName(null); + + getValidPascalCaseIdentifierNameCall.Should().ThrowExactly(); } [Theory] @@ -20,7 +23,9 @@ public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForNullValue() [InlineData("$^123")] public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForInvalidInput(string name) { - Assert.Throws(() => TextHelpers.GetValidPascalCaseIdentifierName(name)); + var getValidPascalCaseIdentifierNameCall = () => TextHelpers.GetValidPascalCaseIdentifierName(name); + + getValidPascalCaseIdentifierNameCall.Should().ThrowExactly(); } [Theory] @@ -34,7 +39,8 @@ public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForInvalidInput(st public void GetValidPascalCaseIdentifierName(string name, string expected) { string result = TextHelpers.GetValidPascalCaseIdentifierName(name); - Assert.Equal(expected, result); + + result.Should().Be(expected); } [Theory] @@ -43,7 +49,9 @@ public void GetValidPascalCaseIdentifierName(string name, string expected) [InlineData(" ")] public void GenerateCommentString_CustomCommentIsNullOrEmptyOrWhiteSpace_Throws(string customComment) { - Assert.Throws(() => TextHelpers.GenerateCommentString(customComment)); + var generateCommentStringCall = () => TextHelpers.GenerateCommentString(customComment); + + generateCommentStringCall.Should().ThrowExactly(); } [Fact] @@ -61,7 +69,7 @@ public void GenerateCommentString_Returns() var result = TextHelpers.GenerateCommentString(customComment); - Assert.Equal(expectedComment, result); + result.Should().Be(expectedComment); } [Theory] @@ -70,7 +78,9 @@ public void GenerateCommentString_Returns() [InlineData(" ")] public void GetEnumerableType_TypeNameIsNullOrWhitespace_Throws(string typeName) { - Assert.Throws(() => TextHelpers.GetEnumerableType(typeName)); + var getEnumerableTypeCall = () => TextHelpers.GetEnumerableType(typeName); + + getEnumerableTypeCall.Should().ThrowExactly(); } [Fact] @@ -80,6 +90,6 @@ public void GetEnumerableType_Returns() var result = TextHelpers.GetEnumerableType(typeName); - Assert.Equal("IEnumerable", result); + result.Should().Be("IEnumerable"); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 46de8e56..338e9806 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using FluentAssertions; using Kontent.Ai.Management.Models.Types; using Kontent.Ai.Management.Models.Types.Elements; using Kontent.Ai.ModelGenerator.Core.Configuration; @@ -38,7 +39,9 @@ public void TryMap_LinkedItemsElementIsNull_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, options, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, options, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -55,7 +58,9 @@ public void TryMap_NotLinkedItemsElement_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -68,7 +73,9 @@ public void TryMap_ContentTypesIsNull_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, null, options, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, null, options, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -82,7 +89,9 @@ public void TryMap_ContentTypesIsEmpty_Throws() ExtendedDeliverModels = true }; - Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -94,7 +103,9 @@ public void TryMap_OptionsIsNull_Throws() }; var element = new LinkedItemsElementMetadataModel(); - Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, null, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, null, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -111,7 +122,9 @@ public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws() ExtendedDeliverModels = false }; - Assert.Throws(() => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); + + tryMapCall.Should().ThrowExactly(); } #region Live models @@ -154,8 +167,9 @@ public void TryMap_Live_CouldNotFindAllowedType_Throws() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - Assert.Throws(() => - TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -198,12 +212,11 @@ public void TryMap_Live_SingleAllowedTypeMultiItems_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.True(result); - Assert.NotNull(typedProperty); - Assert.Equal("Articles_Article", typedProperty.Codename); - Assert.Null(typedProperty.Id); - Assert.Equal("ArticlesArticle", typedProperty.Identifier); - Assert.Equal("IEnumerable
", typedProperty.TypeName); + result.Should().BeTrue(); + typedProperty.Codename.Should().Be("Articles_Article"); + typedProperty.Id.Should().BeNull(); + typedProperty.Identifier.Should().Be("ArticlesArticle"); + typedProperty.TypeName.Should().Be("IEnumerable
"); } [Fact] @@ -246,11 +259,11 @@ public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.True(result); - Assert.Equal("article", typedProperty.Codename); - Assert.Null(typedProperty.Id); - Assert.Equal("Article", typedProperty.Identifier); - Assert.Equal("Article", typedProperty.TypeName); + result.Should().BeTrue(); + typedProperty.Codename.Should().Be("article"); + typedProperty.Id.Should().BeNull(); + typedProperty.Identifier.Should().Be("Article"); + typedProperty.TypeName.Should().Be("Article"); } [Fact] @@ -298,8 +311,8 @@ public void TryMap_Live_MultiAllowedTypesSingleItem_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.False(result); - Assert.Null(typedProperty); + result.Should().BeFalse(); + typedProperty.Should().BeNull(); } [Fact] @@ -347,8 +360,8 @@ public void TryMap_Live_MultiAllowedTypesMultiItems_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); - Assert.False(result); - Assert.Null(typedProperty); + result.Should().BeFalse(); + typedProperty.Should().BeNull(); } #endregion @@ -393,8 +406,9 @@ public void TryMap_Preview_CouldNotFindAllowedType_Throws() limitModel, linkedContentTypeModels.Select(ct => ct.Id)); - Assert.Throws(() => - TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out _)); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out _); + + tryMapCall.Should().ThrowExactly(); } [Fact] @@ -437,11 +451,11 @@ public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.True(result); - Assert.Equal("Articles_Article", typedProperty.Codename); - Assert.Null(typedProperty.Id); - Assert.Equal("ArticlesArticle", typedProperty.Identifier); - Assert.Equal($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", typedProperty.TypeName); + result.Should().BeTrue(); + typedProperty.Codename.Should().Be("Articles_Article"); + typedProperty.Id.Should().BeNull(); + typedProperty.Identifier.Should().Be("ArticlesArticle"); + typedProperty.TypeName.Should().Be($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>"); } [Fact] @@ -484,11 +498,11 @@ public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.True(result); - Assert.Equal("article", typedProperty.Codename); - Assert.Null(typedProperty.Id); - Assert.Equal("Article", typedProperty.Identifier); - Assert.Equal("IEnumerable", typedProperty.TypeName); + result.Should().BeTrue(); + typedProperty.Codename.Should().Be("article"); + typedProperty.Id.Should().BeNull(); + typedProperty.Identifier.Should().Be("Article"); + typedProperty.TypeName.Should().Be("IEnumerable"); } [Fact] @@ -536,8 +550,8 @@ public void TryMap_Preview_MultiAllowedTypesSingleItem_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.False(result); - Assert.Null(typedProperty); + result.Should().BeFalse(); + typedProperty.Should().BeNull(); } [Fact] @@ -585,8 +599,8 @@ public void TryMap_Preview_MultiAllowedTypesMultiItems_Returns() var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - Assert.False(result); - Assert.Null(typedProperty); + result.Should().BeFalse(); + typedProperty.Should().BeNull(); } #endregion diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs index 2b1a90a0..348bacc7 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ManagementCodeGeneratorTests.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using FluentAssertions; using Kontent.Ai.Management; using Kontent.Ai.Management.Configuration; using Kontent.Ai.Management.Models.Shared; @@ -44,7 +45,9 @@ public void Constructor_ManagementIsTrue_Throws() var outputProvider = new Mock(); - Assert.Throws(() => new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, _managementClient)); + var call = () => new ManagementCodeGenerator(mockOptions.Object, outputProvider.Object, _managementClient); + + call.Should().ThrowExactly(); } [Fact] @@ -74,7 +77,7 @@ public void GetClassCodeGenerator_Returns() var result = codeGenerator.GetClassCodeGenerator(contentType, new List()); - Assert.Equal($"{contentTypeCodename}.Generated", result.ClassFilename); + result.ClassFilename.Should().Be($"{contentTypeCodename}.Generated"); } [Fact] @@ -94,10 +97,10 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() await codeGenerator.RunAsync(); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypes); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs")); - Assert.NotEmpty(Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs"))); + Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs").Should().NotBeEmpty(); + Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs")).Should().NotBeEmpty(); // Cleanup Directory.Delete(TempDir, true); @@ -123,11 +126,11 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() await codeGenerator.RunAsync(); - Assert.Equal(NumberOfContentTypes, Directory.GetFiles(Path.GetFullPath(TempDir)).Length); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypes); foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) { - Assert.EndsWith($".{transformFilename}.cs", Path.GetFileName(filepath)); + Path.GetFileName(filepath).Should().EndWith($".{transformFilename}.cs"); } // Cleanup @@ -156,38 +159,17 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; - Assert.Equal(allFilesCount, generatedCount * 2); + var resultFileCount = generatedCount * 2; + + resultFileCount.Should().Be(allFilesCount); foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs")) { var customFileExists = File.Exists(filepath.Replace($".{transformFilename}", "")); - Assert.True(customFileExists); + customFileExists.Should().BeTrue(); } // Cleanup Directory.Delete(TempDir, true); } - - private static IManagementClient CreateManagementClient() - { - var managementModelsProvider = new ManagementModelsProvider(); - var managementClientMock = new Mock(); - - var contentTypeListingResponseModel = new Mock>(); - contentTypeListingResponseModel.As>() - .Setup(c => c.GetEnumerator()) - .Returns(() => managementModelsProvider.ManagementContentTypeModels); - - var contentTypeSnippetListingResponseModel = new Mock>(); - contentTypeSnippetListingResponseModel.As>() - .Setup(c => c.GetEnumerator()) - .Returns(() => managementModelsProvider.ManagementContentTypeSnippetModels); - - managementClientMock.Setup(client => client.ListContentTypeSnippetsAsync()) - .Returns(Task.FromResult(contentTypeSnippetListingResponseModel.Object)); - managementClientMock.Setup(client => client.ListContentTypesAsync()) - .Returns(Task.FromResult(contentTypeListingResponseModel.Object)); - - return managementClientMock.Object; - } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs index 7a8f803f..c3b56357 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/UsedSdkInfoTests.cs @@ -1,4 +1,5 @@ using System; +using FluentAssertions; using Kontent.Ai.ModelGenerator.Options; using Xunit; @@ -9,15 +10,17 @@ public class UsedSdkInfoTests [Fact] public void Constructor_TypeIsNull_Throws() { - var exception = Assert.Throws(() => new UsedSdkInfo(null, "name")); - Assert.Equal("type", exception.ParamName); + var call = () => new UsedSdkInfo(null, "name"); + + call.Should().ThrowExactly().And.ParamName.Should().Be("type"); } [Fact] public void Constructor_NameIsNull_Throws() { - var exception = Assert.Throws(() => new UsedSdkInfo(typeof(string), null)); - Assert.Equal("name", exception.ParamName); + var call = () => new UsedSdkInfo(typeof(string), null); + + call.Should().ThrowExactly().And.ParamName.Should().Be("name"); } [Fact] @@ -25,8 +28,7 @@ public void Constructor_Returns() { var result = new UsedSdkInfo(typeof(string), "name"); - Assert.Equal("name", result.Name); - Assert.NotNull(result.Version); - Assert.NotEmpty(result.Version); + result.Name.Should().Be("name"); + result.Version.Should().NotBeNullOrEmpty(); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs index f380be8b..94465bc1 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using FluentAssertions; using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; @@ -11,7 +12,7 @@ namespace Kontent.Ai.ModelGenerator.Tests; public class ValidationExtensionsTests { [Fact] - public void Validate_ManagementOptions_Success() + public void Validate_ManagementOptions_DoesNotThrow() { var projectId = Guid.NewGuid().ToString(); var codeGeneratorOptions = new CodeGeneratorOptions @@ -24,11 +25,13 @@ public void Validate_ManagementOptions_Success() } }; - codeGeneratorOptions.Validate(); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().NotThrow(); } [Fact] - public void Validate_DeliveryOptions_Success() + public void Validate_DeliveryOptions_DoesNotThrow() { var projectId = Guid.NewGuid().ToString(); var codeGeneratorOptions = new CodeGeneratorOptions @@ -40,13 +43,15 @@ public void Validate_DeliveryOptions_Success() } }; - codeGeneratorOptions.Validate(); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().NotThrow(); } [Theory] [InlineData(true, false)] [InlineData(false, true)] - public void Validate_ExtendedDeliveryModels_Success(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + public void Validate_ExtendedDeliveryModels_DoesNotThrow(bool extendedDeliverModels, bool extendedDeliverPreviewModels) { var projectId = Guid.NewGuid().ToString(); var codeGeneratorOptions = new CodeGeneratorOptions @@ -61,7 +66,9 @@ public void Validate_ExtendedDeliveryModels_Success(bool extendedDeliverModels, } }; - codeGeneratorOptions.Validate(); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().NotThrow(); } [Fact] @@ -72,8 +79,10 @@ public void Validate_DeliveryOptionsIsNull_ThrowsException() DeliveryOptions = null }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal("You have to provide at least the 'ProjectId' argument. See http://bit.ly/k-params for more details on configuration.", exception.Message); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().ThrowExactly() + .And.Message.Should().Be("You have to provide at least the 'ProjectId' argument. See http://bit.ly/k-params for more details on configuration."); } [Fact] @@ -87,7 +96,9 @@ public void Validate_DeliveryOptionsProjectIdIsNull_ThrowsException() } }; - Assert.Throws(() => codeGeneratorOptions.Validate()); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().ThrowExactly(); } [Theory] @@ -101,8 +112,10 @@ public void Validate_ManagementOptionsIsNull_ThrowsException(CodeGeneratorOption }; codeGeneratorOptions.ManagementOptions = null; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal($"You have to provide the 'ProjectId' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration.", exception.Message); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().ThrowExactly() + .And.Message.Should().Be($"You have to provide the 'ProjectId' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration."); } [Theory] @@ -120,8 +133,10 @@ public void Validate_ManagementOptionsProjectIdIsNull_ThrowsException(CodeGenera ApiKey = "apiKey" }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal($"You have to provide the 'ProjectId' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration.", exception.Message); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().ThrowExactly() + .And.Message.Should().Be($"You have to provide the 'ProjectId' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration."); } [Theory] @@ -143,8 +158,10 @@ public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException( ApiKey = apiKey }; - var exception = Assert.Throws(() => codeGeneratorOptions.Validate()); - Assert.Equal($"You have to provide the 'ApiKey' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration.", exception.Message); + var validateCall = () => codeGeneratorOptions.Validate(); + + validateCall.Should().ThrowExactly() + .And.Message.Should().Be($"You have to provide the 'ApiKey' to generate type for {expectedSdkName} SDK. See {expectedUrl} for more details on configuration."); } public static IEnumerable OptionsUsingManagementApiOptionsData => new List From 1da9e8416d7f4c4809ef0dca64a7aadcbdc98bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 19 Jan 2023 06:44:12 +0100 Subject: [PATCH 27/48] 90 update docs --- README.md | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1972ee24..615b309b 100644 --- a/README.md +++ b/README.md @@ -47,16 +47,18 @@ To learn how to generate executables for your favorite target platform, follow t ### Delivery API parameters -| Short key | Long key | Required | Default value | Description | -| --------- | :------------------: | :------: | :---------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID | -| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) | -| `-o` | `--outputdir` | False | `\.` | An output folder path | -| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. | -| `-t` | `--withtypeprovider` | False | `true` | Indicates whether the `CustomTypeProvider` class should be generated (see [Customizing the strong-type binding logic](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/strongly-typed-models.md#customizing-the-strong-type-binding-logic) for more info) | -| `-s` | `--structuredmodel` | False | `false` | Generates `IRichTextContent` instead of `string` for rich-text elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/rich-text/structured-rich-text-rendering.md) | -| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | -| `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | +| Short key | Long key | Required | Default value | Description | +| --------- | :-------------------------------------: | :------: | :---------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID | +| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) | +| `-o` | `--outputdir` | False | `\.` | An output folder path | +| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. | +| `-t` | `--withtypeprovider` | False | `true` | Indicates whether the `CustomTypeProvider` class should be generated (see [Customizing the strong-type binding logic](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/strongly-typed-models.md#customizing-the-strong-type-binding-logic) for more info) | +| `-s` | `--structuredmodel` | False | `false` | Generates `IRichTextContent` instead of `string` for rich-text elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/rich-text/structured-rich-text-rendering.md) | +| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | +| `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | +| `-e` | `--extendeddelivermodels` | False | `false` | Indicates whether extended deliver models should be generated | +| `-r` | `--extendeddeliverpreviewmodels` | False | `false` | Indicates whether extended preview deliver models should be generated | ### CLI Syntax @@ -101,6 +103,33 @@ namespace KontentAiModels } ``` +#### Extended delivery models +```csharp +using System; +using System.Collections.Generic; +using Kontent.Ai.Delivery.Abstractions; + +namespace KontentAiModels +{ + public partial class CompleteContentType + { + public string Text { get; set; } + public string RichText { get; set; } + public IRichTextContent RichTextStructured { get; set; } + public decimal? Number { get; set; } + public IEnumerable MultipleChoice { get; set; } + public DateTime? DateTime { get; set; } + public IEnumerable Asset { get; set; } + public IEnumerable ModularContent { get; set; } + public IEnumerable Subpages { get; set; } + public IEnumerable Taxonomy { get; set; } + public string UrlSlug { get; set; } + public string CustomElement { get; set; } + public ContentItemSystemAttributes System { get; set; } + } +} +``` + ### Customizing models - Handling content element constraints Currently, the generator is built on top of the Delivery API which doesn't provide information about content element constraints such as "Allowed Content Types" or "Limit number of items". In case you want your models to be more specific, this is the best practice on how to extend them: From 99a226197e4d89b7d7cfa54644ee860df4708620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 26 Jan 2023 15:02:35 +0100 Subject: [PATCH 28/48] 90 include subpages element as well --- .../Common/Property.cs | 3 +- .../ExtendedDeliveryCodeGenerator.cs | 2 +- .../Helpers/TypedDeliveryPropertyMapper.cs | 53 +- ...pe_CompiledCode_ExtendedDeliveryModels.txt | 4 + ...mpiledCode_TypedExtendedDeliveryModels.txt | 4 + .../ExtendedDeliveryCodeGeneratorTests.cs | 38 +- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 53 +- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 33 +- .../TypedDeliveryPropertyMapperTests.cs | 459 +++++++++--------- .../TestHelpers/LinkedItemsContentTypeData.cs | 2 +- .../TestHelpers/SubpagesContentTypeData.cs | 92 ++++ .../TestHelpers/TestDataGenerator.cs | 10 + 12 files changed, 491 insertions(+), 262 deletions(-) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 0cc86602..38086682 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -48,6 +48,7 @@ public class Property { ElementMetadataType.DateTime.ToString(), "DateTime?" }, { ElementMetadataType.Asset.ToString(), TextHelpers.GetEnumerableType(nameof(IAsset)) }, { ElementMetadataType.LinkedItems.ToString(), null }, + { ElementMetadataType.Subpages.ToString(), null }, { ElementMetadataType.Taxonomy.ToString(), TextHelpers.GetEnumerableType(nameof(ITaxonomyTerm)) }, { ElementMetadataType.UrlSlug.ToString(), "string" }, { ElementMetadataType.Custom.ToString(), "string" } @@ -110,7 +111,7 @@ public static Property FromContentTypeElement(ElementMetadataBase element, strin { if (IsContentTypeSupported(element.Type.ToString(), true)) { - var resultElementType = element.Type == ElementMetadataType.LinkedItems + var resultElementType = element.Type is ElementMetadataType.LinkedItems or ElementMetadataType.Subpages ? elementType : ExtendedDeliverElementTypesDictionary[elementType]; diff --git a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs index 16e4c160..f6bcb182 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs @@ -105,7 +105,7 @@ internal IEnumerable GetClassCodeGenerators(ContentTypeModel private void AddProperty(ElementMetadataBase el, ref ClassDefinition classDefinition, ref ClassDefinition typedClassDefinition, List contentTypes) { var elementType = DeliveryElementHelper.GetElementType(Options, el.Type.ToString()); - if (elementType == ElementMetadataType.LinkedItems.ToString()) + if (elementType == ElementMetadataType.LinkedItems.ToString() || elementType == ElementMetadataType.Subpages.ToString()) { if (TypedDeliveryPropertyMapper.TryMap(el, contentTypes, Options, out var typedProperty)) { diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index 4212a872..783fc35c 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using Kontent.Ai.Management.Extensions; +using Kontent.Ai.Management.Models.Shared; namespace Kontent.Ai.ModelGenerator.Core.Helpers; @@ -18,25 +19,21 @@ public static bool TryMap( CodeGeneratorOptions options, out Property typedProperty) { - Validate(contentTypes, options); + Validate(contentTypes, el, options); - var linkedItemsElement = el.ToElement(); - if (linkedItemsElement == null) - { - throw new ArgumentNullException(); - } + var elementOptions = GetElementOptions(el); - if (!linkedItemsElement.AllowedTypes.Any() || - linkedItemsElement.AllowedTypes.Count() > 1) + if (!elementOptions.AllowedTypes.Any() || + elementOptions.AllowedTypes.Count() > 1) { typedProperty = null; return false; } - var allowedContentType = GetAllowedContentType(linkedItemsElement.AllowedTypes.First().Id.Value, contentTypes); + var allowedContentType = GetAllowedContentType(elementOptions.AllowedTypes.First().Id.Value, contentTypes); var allowedContentTypeCodename = TextHelpers.GetValidPascalCaseIdentifierName(allowedContentType.Codename); - if (linkedItemsElement.ItemCountLimit is { Condition: LimitType.Exactly, Value: 1 }) + if (elementOptions.ItemCountLimit is { Condition: LimitType.Exactly, Value: 1 }) { var singleAllowedContentTypeCodename = options.ExtendedDeliverPreviewModels ? TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName) @@ -54,7 +51,7 @@ public static bool TryMap( return true; } - private static void Validate(List contentTypes, CodeGeneratorOptions options) + private static void Validate(List contentTypes, ElementMetadataBase element, CodeGeneratorOptions options) { if (contentTypes == null) { @@ -66,6 +63,11 @@ private static void Validate(List contentTypes, CodeGeneratorO throw new ArgumentException($"{nameof(contentTypes)} cannot be empty"); } + if (element == null) + { + throw new ArgumentNullException(nameof(element)); + } + if (options == null) { throw new ArgumentNullException(nameof(options)); @@ -95,4 +97,33 @@ private static Property CreateProperty(ElementMetadataBase element, string eleme element, TextHelpers.GetEnumerableType(elementType), GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)); + + private static (IEnumerable AllowedTypes, LimitModel ItemCountLimit) GetElementOptions(ElementMetadataBase el) + { + if (el.Type == ElementMetadataType.LinkedItems) + { + var linkedItemsElement = el.ToElement(); + ValidateTypedElement(linkedItemsElement); + + return (linkedItemsElement.AllowedTypes, linkedItemsElement.ItemCountLimit); + } + + if (el.Type == ElementMetadataType.Subpages) + { + var subpagesElement = el.ToElement(); + ValidateTypedElement(subpagesElement); + + return (subpagesElement.AllowedContentTypes, subpagesElement.ItemCountLimit); + } + + throw new ArgumentException(); + + static void ValidateTypedElement(ElementMetadataBase element) + { + if (element == null) + { + throw new ArgumentNullException(); + } + } + } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt index 72371d33..d3edeea4 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt @@ -27,6 +27,10 @@ namespace KontentAiModels public decimal? Number { get; set; } public string RichText { get; set; } public IRichTextContent RichTextStructured { get; set; } + public IEnumerable SubpagesArticle { get; set; } + public IEnumerable SubpagesBlog { get; set; } + public IEnumerable SubpagesCoffees { get; set; } + public IEnumerable SubpagesHeroes { get; set; } public IContentItemSystemAttributes System { get; set; } public IEnumerable Taxonomy { get; set; } public string Text { get; set; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt index a16e448d..97ec8b39 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt @@ -17,6 +17,10 @@ namespace KontentAiModels { public Article ModularContentArticleSingle => ModularContentArticle.OfType
().FirstOrDefault(); + public Article SubpagesArticleSingle => SubpagesArticle.OfType
().FirstOrDefault(); + public IEnumerable ModularContentHeroesHeroTyped => ModularContentHeroes.OfType(); + + public IEnumerable SubpagesHeroesHeroTyped => SubpagesHeroes.OfType(); } } \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index 35995ad6..3202b30e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -104,11 +104,22 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, - LinkedItemsContentTypeData.MultiAllowedTypesMultiItems + LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, + SubpagesContentTypeData.SingleAllowedTypeMultiItems, + SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, + SubpagesContentTypeData.MultiAllowedTypesSingleItem, + SubpagesContentTypeData.MultiAllowedTypesMultiItems, } }; - var contentTypes = new List { contentType, LinkedItemsContentTypeData.ArticleContentType, LinkedItemsContentTypeData.HeroContentType }; + var contentTypes = new List + { + contentType, + LinkedItemsContentTypeData.ArticleContentType, + LinkedItemsContentTypeData.HeroContentType, + SubpagesContentTypeData.HeroContentType, + SubpagesContentTypeData.ArticleContentType + }; var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); @@ -121,12 +132,19 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, $"IEnumerable<{LinkedItemsContentTypeData.HeroContentType.Name}>", "ModularContentHeroes_Hero"), - Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, LinkedItemsContentTypeData.ArticleContentType.Name) + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, LinkedItemsContentTypeData.ArticleContentType.Name), + Property.FromContentTypeElement( + SubpagesContentTypeData.SingleAllowedTypeMultiItems, + $"IEnumerable<{SubpagesContentTypeData.HeroContentType.Name}>", + "SubpagesHeroes_Hero"), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, SubpagesContentTypeData.ArticleContentType.Name) }); expectedTypedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List { "ModularContentHeroes_Hero", - "modular_content_article" + "modular_content_article", + "SubpagesHeroes_Hero", + "subpages_article" }); var expectedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); @@ -135,14 +153,22 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType) + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), + Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), + Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType) }); expectedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List { "modular_content_heroes", "modular_content_article", "modular_content_blog", - "modular_content_coffees" + "modular_content_coffees", + "subpages_heroes", + "subpages_article", + "subpages_blog", + "subpages_coffees" }); var expected = new List diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index 9eda3ddc..210976d4 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -43,8 +43,12 @@ public ExtendedDeliveryClassCodeGeneratorTests() TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset), ElementMetadataType.Asset.ToString())); - // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItemsTypeName = "Hero"; + var singleAllowedTypeExactlySingleItemTypeName = "Article"; + + #region LinkedItems + + // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); @@ -52,9 +56,8 @@ public ExtendedDeliveryClassCodeGeneratorTests() ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); // Linked items element limited to a single type with at most or exactly 1 item. - var singleAllowedTypeExactlySingleItemTypeName = "Article"; var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. - GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); @@ -72,7 +75,7 @@ public ExtendedDeliveryClassCodeGeneratorTests() // Linked items element limited to multiple types with at least 1 item. var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. - GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); + GenerateElementMetadataBase(Guid.Parse("9fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); multiAllowedTypesMultiItems.AllowedTypes = new List(new List { Reference.ByCodename("Hero"), @@ -81,6 +84,48 @@ public ExtendedDeliveryClassCodeGeneratorTests() multiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + #endregion + + #region Subpages + + // Linked items elements are limited to a single type with at least 1 item. + var subpagesSingleAllowedTypeMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "subpages_heroes", ElementMetadataType.Subpages); + subpagesSingleAllowedTypeMultiItems.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); + subpagesSingleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + // Linked items element limited to a single type with at most or exactly 1 item. + var subpagesSingleAllowedTypeExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "subpages_article", ElementMetadataType.Subpages); + subpagesSingleAllowedTypeExactlySingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); + singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeExactlySingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. + var subpagesMultiAllowedTypesSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "subpages_blog", ElementMetadataType.Subpages); + subpagesMultiAllowedTypesSingleItem.AllowedContentTypes = new List(new List + { + Reference.ByCodename("Hero"), + Reference.ByCodename("Article") + }); + subpagesMultiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesSingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + // Linked items element limited to multiple types with at least 1 item. + var subpagesMultiAllowedTypesMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee6"), "subpages_coffees", ElementMetadataType.Subpages); + subpagesMultiAllowedTypesMultiItems.AllowedContentTypes = new List(new List + { + Reference.ByCodename("Hero"), + Reference.ByCodename("Article") + }); + subpagesMultiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + + #endregion + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), ElementMetadataType.RichText + Property.StructuredSuffix)); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index 1a355288..0c27c887 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -20,8 +20,12 @@ public class TypedExtendedDeliveryClassCodeGeneratorTests : ClassCodeGeneratorTe { public TypedExtendedDeliveryClassCodeGeneratorTests() { - // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItemsTypeName = "Hero"; + var singleAllowedTypeExactlySingleItemTypeName = "Article"; + + #region LinkedItems + + // Linked items elements are limited to a single type with at least 1 item. var singleAllowedTypeMultiItemsTypeCodename = "modular_content_heroes"; var singleAllowedTypeMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.NewGuid(), singleAllowedTypeMultiItemsTypeCodename, ElementMetadataType.LinkedItems); @@ -33,12 +37,35 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() $"{singleAllowedTypeMultiItemsTypeCodename}_{singleAllowedTypeMultiItemsTypeName}")); // Linked items element limited to a single type with at most or exactly 1 item. - var singleAllowedTypeExactlySingleItemTypeName = "Article"; var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. - GenerateElementMetadataBase(Guid.NewGuid(), "modular_content_article", ElementMetadataType.LinkedItems); + GenerateElementMetadataBase(Guid.NewGuid(), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, singleAllowedTypeExactlySingleItemTypeName)); + + #endregion + + #region Subpages + + // Subpages elements are limited to a single type with at least 1 item. + var subpagesSingleAllowedTypeMultiItemsTypeCodename = "subpages_heroes"; + var subpagesSingleAllowedTypeMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.NewGuid(), subpagesSingleAllowedTypeMultiItemsTypeCodename, ElementMetadataType.Subpages); + subpagesSingleAllowedTypeMultiItems.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); + subpagesSingleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement( + subpagesSingleAllowedTypeMultiItems, + TextHelpers.GetEnumerableType(singleAllowedTypeMultiItemsTypeName), + $"{subpagesSingleAllowedTypeMultiItemsTypeCodename}_{singleAllowedTypeMultiItemsTypeName}")); + + // Subpages element limited to a single type with at most or exactly 1 item. + var subpagesSingleAllowedTypeExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.NewGuid(), "subpages_article", ElementMetadataType.Subpages); + subpagesSingleAllowedTypeExactlySingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); + subpagesSingleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeExactlySingleItem, singleAllowedTypeExactlySingleItemTypeName)); + + #endregion } [Fact] diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 338e9806..25fd4aa3 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -27,7 +27,7 @@ public class TypedDeliveryPropertyMapperTests }; [Fact] - public void TryMap_LinkedItemsElementIsNull_Throws() + public void TryMap_ElementIsNull_Throws() { var contentTypes = new List { @@ -45,7 +45,7 @@ public void TryMap_LinkedItemsElementIsNull_Throws() } [Fact] - public void TryMap_NotLinkedItemsElement_Throws() + public void TryMap_NotLinkedItemsElementOrSubpages_Throws() { var contentTypes = new List { @@ -60,13 +60,13 @@ public void TryMap_NotLinkedItemsElement_Throws() var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); - tryMapCall.Should().ThrowExactly(); + tryMapCall.Should().ThrowExactly(); } - [Fact] - public void TryMap_ContentTypesIsNull_Throws() + [Theory] + [MemberData(nameof(GetBasicAllowedElements))] + public void TryMap_ContentTypesIsNull_Throws(ElementMetadataBase element) { - var element = new LinkedItemsElementMetadataModel(); var options = new CodeGeneratorOptions { ExtendedDeliverPreviewModels = false, @@ -78,11 +78,11 @@ public void TryMap_ContentTypesIsNull_Throws() tryMapCall.Should().ThrowExactly(); } - [Fact] - public void TryMap_ContentTypesIsEmpty_Throws() + [Theory] + [MemberData(nameof(GetBasicAllowedElements))] + public void TryMap_ContentTypesIsEmpty_Throws(ElementMetadataBase element) { var contentTypes = new List(); - var element = new LinkedItemsElementMetadataModel(); var options = new CodeGeneratorOptions { ExtendedDeliverPreviewModels = false, @@ -94,28 +94,28 @@ public void TryMap_ContentTypesIsEmpty_Throws() tryMapCall.Should().ThrowExactly(); } - [Fact] - public void TryMap_OptionsIsNull_Throws() + [Theory] + [MemberData(nameof(GetBasicAllowedElements))] + public void TryMap_OptionsIsNull_Throws(ElementMetadataBase element) { var contentTypes = new List { new ContentTypeModel() }; - var element = new LinkedItemsElementMetadataModel(); var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, null, out _); tryMapCall.Should().ThrowExactly(); } - [Fact] - public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws() + [Theory] + [MemberData(nameof(GetBasicAllowedElements))] + public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws(ElementMetadataBase element) { var contentTypes = new List { new ContentTypeModel() }; - var element = new LinkedItemsElementMetadataModel(); var options = new CodeGeneratorOptions { ExtendedDeliverPreviewModels = false, @@ -129,23 +129,10 @@ public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws() #region Live models - [Fact] - public void TryMap_Live_CouldNotFindAllowedType_Throws() + [Theory] + [MemberData(nameof(GetNonMatchingAllowedTypesElements))] + public void TryMap_Live_CouldNotFindAllowedType_Throws(ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.AtLeast, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - } - }; var allContentTypes = new List() { @@ -161,35 +148,15 @@ public void TryMap_Live_CouldNotFindAllowedType_Throws() } }; - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "articles", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } - [Fact] - public void TryMap_Live_SingleAllowedTypeMultiItems_Returns() + [Theory] + [MemberData(nameof(GetSingleAllowedTypeMultiItems))] + public void TryMap_Live_SingleAllowedTypeMultiItems_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.AtLeast, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - } - }; - var allContentTypes = new List() { new ContentTypeModel @@ -204,12 +171,6 @@ public void TryMap_Live_SingleAllowedTypeMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "articles", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); result.Should().BeTrue(); @@ -219,24 +180,10 @@ public void TryMap_Live_SingleAllowedTypeMultiItems_Returns() typedProperty.TypeName.Should().Be("IEnumerable
"); } - [Fact] - public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns() + [Theory] + [MemberData(nameof(GetSingleAllowedTypeExactlySingleItem))] + public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.Exactly, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - } - }; - var allContentTypes = new List() { new ContentTypeModel @@ -251,12 +198,6 @@ public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "article", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); result.Should().BeTrue(); @@ -266,29 +207,10 @@ public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns() typedProperty.TypeName.Should().Be("Article"); } - [Fact] - public void TryMap_Live_MultiAllowedTypesSingleItem_Returns() + [Theory] + [MemberData(nameof(GetMultiAllowedTypesSingleItem))] + public void TryMap_Live_MultiAllowedTypesSingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.Exactly, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "blog", - Id = Guid.NewGuid() - } - }; - var allContentTypes = new List() { new ContentTypeModel @@ -303,41 +225,16 @@ public void TryMap_Live_MultiAllowedTypesSingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "article", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); result.Should().BeFalse(); typedProperty.Should().BeNull(); } - [Fact] - public void TryMap_Live_MultiAllowedTypesMultiItems_Returns() + [Theory] + [MemberData(nameof(GetMultiAllowedTypesMultiItems))] + public void TryMap_Live_MultiAllowedTypesMultiItems_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.AtLeast, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "blog", - Id = Guid.NewGuid() - } - }; - var allContentTypes = new List() { new ContentTypeModel @@ -352,12 +249,6 @@ public void TryMap_Live_MultiAllowedTypesMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "articles", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); result.Should().BeFalse(); @@ -368,15 +259,10 @@ public void TryMap_Live_MultiAllowedTypesMultiItems_Returns() #region Preview models - [Fact] - public void TryMap_Preview_CouldNotFindAllowedType_Throws() + [Theory] + [MemberData(nameof(GetNonMatchingAllowedTypesElements))] + public void TryMap_Preview_CouldNotFindAllowedType_Throws(ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.AtLeast, - Value = 1 - }; - var linkedContentTypeModels = new List() { new ContentTypeModel @@ -400,35 +286,15 @@ public void TryMap_Preview_CouldNotFindAllowedType_Throws() } }; - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "articles", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } - [Fact] - public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns() + [Theory] + [MemberData(nameof(GetSingleAllowedTypeMultiItems))] + public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.AtLeast, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - } - }; - var allContentTypes = new List() { new ContentTypeModel @@ -443,12 +309,6 @@ public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "articles", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); result.Should().BeTrue(); @@ -458,24 +318,10 @@ public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns() typedProperty.TypeName.Should().Be($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>"); } - [Fact] - public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns() + [Theory] + [MemberData(nameof(GetSingleAllowedTypeExactlySingleItem))] + public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.Exactly, - Value = 1 - }; - - var linkedContentTypeModels = new List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - } - }; - var allContentTypes = new List() { new ContentTypeModel @@ -490,12 +336,6 @@ public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "article", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); result.Should().BeTrue(); @@ -505,29 +345,34 @@ public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns() typedProperty.TypeName.Should().Be("IEnumerable"); } - [Fact] - public void TryMap_Preview_MultiAllowedTypesSingleItem_Returns() + [Theory] + [MemberData(nameof(GetMultiAllowedTypesSingleItem))] + public void TryMap_Preview_MultiAllowedTypesSingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) { - var limitModel = new LimitModel - { - Condition = LimitType.Exactly, - Value = 1 - }; - - var linkedContentTypeModels = new List() + var allContentTypes = new List() { new ContentTypeModel { - Codename = "article", + Codename = "grinder", Id = Guid.NewGuid() }, new ContentTypeModel { - Codename = "blog", + Codename = "coffee", Id = Guid.NewGuid() } - }; + }.Union(linkedContentTypeModels).ToList(); + + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); + + result.Should().BeFalse(); + typedProperty.Should().BeNull(); + } + [Theory] + [MemberData(nameof(GetMultiAllowedTypesMultiItems))] + public void TryMap_Preview_MultiAllowedTypesMultiItems_Returns(List linkedContentTypeModels, ElementMetadataBase element) + { var allContentTypes = new List() { new ContentTypeModel @@ -542,20 +387,21 @@ public void TryMap_Preview_MultiAllowedTypesSingleItem_Returns() } }.Union(linkedContentTypeModels).ToList(); - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "article", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); result.Should().BeFalse(); typedProperty.Should().BeNull(); } - [Fact] - public void TryMap_Preview_MultiAllowedTypesMultiItems_Returns() + #endregion + + public static IEnumerable GetBasicAllowedElements() + { + yield return new object[] { new LinkedItemsElementMetadataModel() }; + yield return new object[] { new SubpagesElementMetadataModel() }; + } + + public static IEnumerable GetNonMatchingAllowedTypesElements() { var limitModel = new LimitModel { @@ -569,39 +415,182 @@ public void TryMap_Preview_MultiAllowedTypesMultiItems_Returns() { Codename = "article", Id = Guid.NewGuid() - }, + } + }; + + yield return new object[] + { + TestDataGenerator.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + yield return new object[] + { + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + } + + public static IEnumerable GetSingleAllowedTypeMultiItems() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { new ContentTypeModel { - Codename = "blog", + Codename = "article", Id = Guid.NewGuid() } }; - var allContentTypes = new List() + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + } + + public static IEnumerable GetSingleAllowedTypeExactlySingleItem() + { + var limitModel = new LimitModel + { + Condition = LimitType.Exactly, + Value = 1 + }; + + var linkedContentTypeModels = new List() { new ContentTypeModel { - Codename = "grinder", + Codename = "article", + Id = Guid.NewGuid() + } + }; + + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + } + + public static IEnumerable GetMultiAllowedTypesSingleItem() + { + var limitModel = new LimitModel + { + Condition = LimitType.Exactly, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", Id = Guid.NewGuid() }, new ContentTypeModel { - Codename = "coffee", + Codename = "blog", Id = Guid.NewGuid() } - }.Union(linkedContentTypeModels).ToList(); + }; - var element = TestDataGenerator.GenerateLinkedItemsElement( - Guid.NewGuid().ToString(), - "articles", - limitModel, - linkedContentTypeModels.Select(ct => ct.Id)); + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + } - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); + public static IEnumerable GetMultiAllowedTypesMultiItems() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtLeast, + Value = 1 + }; - result.Should().BeFalse(); - typedProperty.Should().BeNull(); - } + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "blog", + Id = Guid.NewGuid() + } + }; - #endregion + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "articles", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs index 2336e9d3..bd4ffbe1 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs @@ -79,7 +79,7 @@ private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesSingleIt private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesMultiItems() { var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. - GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); + GenerateElementMetadataBase(Guid.Parse("9fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_coffees", ElementMetadataType.LinkedItems); multiAllowedTypesMultiItems.AllowedTypes = new List(new List { Reference.ById(HeroContentType.Id), diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs new file mode 100644 index 00000000..e92e8bb2 --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using Kontent.Ai.Management.Models.Shared; +using Kontent.Ai.Management.Models.Types; +using Kontent.Ai.Management.Models.Types.Elements; + +namespace Kontent.Ai.ModelGenerator.Tests.TestHelpers; + +public static class SubpagesContentTypeData +{ + public static ContentTypeModel HeroContentType = new ContentTypeModel + { + Name = "Hero", + Id = Guid.NewGuid(), + Codename = "hero" + }; + + public static ContentTypeModel ArticleContentType = new ContentTypeModel + { + Name = "Article", + Id = Guid.NewGuid(), + Codename = "article" + }; + + /// + /// Represents linked items element limited to a single type with at least 1 item + /// + public static SubpagesElementMetadataModel SingleAllowedTypeMultiItems = GenerateSingleAllowedTypeMultiItems(); + + /// + /// Represents linked items element limited to a single type with at most or exactly 1 item + /// + public static SubpagesElementMetadataModel SingleAllowedTypeExactlySingleItem = GenerateSingleAllowedTypeExactlySingleItem(); + + /// + /// Represents linked items element limited to multiple types with at least 1 at most or exactly 1 item + /// + public static SubpagesElementMetadataModel MultiAllowedTypesSingleItem = GenerateMultiAllowedTypesSingleItem(); + + /// + /// Represents linked items element limited to multiple types with at least 1 item + /// + public static SubpagesElementMetadataModel MultiAllowedTypesMultiItems = GenerateMultiAllowedTypesMultiItems(); + + private static SubpagesElementMetadataModel GenerateSingleAllowedTypeMultiItems() + { + var singleAllowedTypeMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "subpages_heroes", ElementMetadataType.Subpages); + singleAllowedTypeMultiItems.AllowedContentTypes = new List(new List { Reference.ById(HeroContentType.Id) }); + singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + + return singleAllowedTypeMultiItems; + } + + private static SubpagesElementMetadataModel GenerateSingleAllowedTypeExactlySingleItem() + { + var singleAllowedTypeExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "subpages_article", ElementMetadataType.Subpages); + singleAllowedTypeExactlySingleItem.AllowedContentTypes = new List(new List { Reference.ById(ArticleContentType.Id) }); + singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + + return singleAllowedTypeExactlySingleItem; + } + + private static SubpagesElementMetadataModel GenerateMultiAllowedTypesSingleItem() + { + var multiAllowedTypesSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "subpages_blog", ElementMetadataType.Subpages); + multiAllowedTypesSingleItem.AllowedContentTypes = new List(new List + { + Reference.ById(HeroContentType.Id), + Reference.ById(ArticleContentType.Id) + }); + multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + + return multiAllowedTypesSingleItem; + } + + private static SubpagesElementMetadataModel GenerateMultiAllowedTypesMultiItems() + { + var multiAllowedTypesMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee6"), "subpages_coffees", ElementMetadataType.Subpages); + multiAllowedTypesMultiItems.AllowedContentTypes = new List(new List + { + Reference.ById(HeroContentType.Id), + Reference.ById(ArticleContentType.Id) + }); + multiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; + + return multiAllowedTypesMultiItems; + } +} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs index fa696fc6..eb9429f6 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/TestDataGenerator.cs @@ -37,4 +37,14 @@ public static LinkedItemsElementMetadataModel GenerateLinkedItemsElement(string return element; } + + public static SubpagesElementMetadataModel GenerateSubpagesElement(string elementId, string elementCodename, LimitModel limitModel, IEnumerable allowedTypesIds) + { + var element = (SubpagesElementMetadataModel)GenerateElementMetadataBase(Guid.Parse(elementId), elementCodename, ElementMetadataType.Subpages); + + element.AllowedContentTypes = allowedTypesIds.Select(Reference.ById); + element.ItemCountLimit = limitModel; + + return element; + } } From 1f6b019229358c9303bad4246c37fa53787a34e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 9 Feb 2023 13:51:41 +0100 Subject: [PATCH 29/48] 90 bump nuget packages --- .../Kontent.Ai.ModelGenerator.Core.csproj | 4 ++-- .../Kontent.Ai.ModelGenerator.csproj | 2 +- .../Kontent.Ai.ModelGenerator.Tests.csproj | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj b/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj index 6e09c73a..dd828063 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj +++ b/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj @@ -25,13 +25,13 @@ - + - + diff --git a/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj b/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj index 79656d1b..1a934051 100644 --- a/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj +++ b/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj @@ -36,7 +36,7 @@ - + diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj index 68fa4b9e..bb30d192 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj +++ b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj @@ -59,7 +59,7 @@ - + From 1c4f102303b7b0d57607c853c5161b56c092181b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 9 Feb 2023 14:45:46 +0100 Subject: [PATCH 30/48] 90 remove separate generation of preview models --- README.md | 1 - .../Configuration/CodeGeneratorOptions.cs | 6 - .../CodeGeneratorOptionsExtensions.cs | 4 +- .../Helpers/TypedDeliveryPropertyMapper.cs | 17 +- .../Options/ArgHelpers.cs | 4 +- .../Options/ArgMappingsRegister.cs | 3 +- .../ArgHelpersTests.cs | 17 +- .../Common/ClassCodeGeneratorFactoryTests.cs | 18 +- .../CodeGeneratorOptionsExtensionsTests.cs | 91 ++++----- .../ExtendedDeliveryCodeGeneratorTests.cs | 120 ++---------- .../TypedDeliveryPropertyMapperTests.cs | 181 +----------------- .../ValidationExtensionsTests.cs | 46 +---- 12 files changed, 74 insertions(+), 434 deletions(-) diff --git a/README.md b/README.md index 615b309b..96efc0d6 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ To learn how to generate executables for your favorite target platform, follow t | `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | | `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | | `-e` | `--extendeddelivermodels` | False | `false` | Indicates whether extended deliver models should be generated | -| `-r` | `--extendeddeliverpreviewmodels` | False | `false` | Indicates whether extended preview deliver models should be generated | ### CLI Syntax diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs index 92cc5e53..159758bb 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs @@ -6,7 +6,6 @@ namespace Kontent.Ai.ModelGenerator.Core.Configuration; public class CodeGeneratorOptions { private const bool DefaultExtendedDeliverModels = false; - private const bool DefaultExtendedDeliverPreviewModels = false; private const bool DefaultGeneratePartials = true; private const bool DefaultWithTypeProvider = true; private const bool DefaultStructuredModel = false; @@ -28,11 +27,6 @@ public class CodeGeneratorOptions /// public bool ExtendedDeliverModels { get; set; } = DefaultExtendedDeliverModels; - /// - /// Indicates whether the extended preview Delivery models should be generated - /// - public bool ExtendedDeliverPreviewModels { get; set; } = DefaultExtendedDeliverPreviewModels; - /// /// Namespace name of the generated classes /// diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index 71b4f22b..b7713cfd 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -3,10 +3,10 @@ public static class CodeGeneratorOptionsExtensions { public static bool ManagementApi(this CodeGeneratorOptions options) => - options.ManagementApi && !options.ExtendedDeliverModels && !options.ExtendedDeliverPreviewModels; + options.ManagementApi && !options.ExtendedDeliverModels; public static bool ExtendedDeliveryModels(this CodeGeneratorOptions options) => - !options.ManagementApi && (options.ExtendedDeliverModels || options.ExtendedDeliverPreviewModels); + !options.ManagementApi && options.ExtendedDeliverModels; public static bool DeliveryApi(this CodeGeneratorOptions options) => !options.ManagementApi() && !options.ExtendedDeliveryModels(); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index 783fc35c..b3d87113 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -2,7 +2,6 @@ using Kontent.Ai.Management.Models.Types; using Kontent.Ai.ModelGenerator.Core.Common; using Kontent.Ai.ModelGenerator.Core.Configuration; -using Kontent.Ai.ModelGenerator.Core.Generators.Class; using System; using System.Collections.Generic; using System.Linq; @@ -35,19 +34,11 @@ public static bool TryMap( if (elementOptions.ItemCountLimit is { Condition: LimitType.Exactly, Value: 1 }) { - var singleAllowedContentTypeCodename = options.ExtendedDeliverPreviewModels - ? TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName) - : allowedContentTypeCodename; - - typedProperty = Property.FromContentTypeElement(el, singleAllowedContentTypeCodename); + typedProperty = Property.FromContentTypeElement(el, allowedContentTypeCodename); return true; } - var multipleAllowedContentTypeCodename = options.ExtendedDeliverPreviewModels - ? ContentItemClassCodeGenerator.DefaultContentItemClassName - : allowedContentTypeCodename; - - typedProperty = CreateProperty(el, multipleAllowedContentTypeCodename, allowedContentTypeCodename); + typedProperty = CreateProperty(el, allowedContentTypeCodename); return true; } @@ -93,9 +84,9 @@ private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List $"{codename}_{typeName}"; - private static Property CreateProperty(ElementMetadataBase element, string elementType, string propertyName) => Property.FromContentTypeElement( + private static Property CreateProperty(ElementMetadataBase element, string propertyName) => Property.FromContentTypeElement( element, - TextHelpers.GetEnumerableType(elementType), + TextHelpers.GetEnumerableType(propertyName), GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)); private static (IEnumerable AllowedTypes, LimitModel ItemCountLimit) GetElementOptions(ElementMetadataBase el) diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index 41dfb3e0..04d01d85 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -56,7 +56,6 @@ private static IDictionary GetSpecificSwitchMappings(string[] ar { var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); - var extendedDeliverPreviewDecidingArgs = new DecidingArgs("-r", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels))); for (var i = 0; i < args.Length; i++) { @@ -67,8 +66,7 @@ private static IDictionary GetSpecificSwitchMappings(string[] ar return ArgMappingsRegister.ManagementMappings; } - if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName || - args[i] == extendedDeliverPreviewDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverPreviewDecidingArgs.FullArgName) + if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName) { return ArgMappingsRegister.ExtendedDeliveryMappings; } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs index 6ceb5f07..ea7f6fa7 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs @@ -33,8 +33,7 @@ internal class ArgMappingsRegister { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) }, { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, - { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, - { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } + { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) } }; public static readonly IDictionary ManagementMappings = new Dictionary diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index 7039ff5e..38d7afc6 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -49,8 +49,7 @@ public class ArgHelpersTests { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) }, { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, - { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) }, - { "-r", nameof(CodeGeneratorOptions.ExtendedDeliverPreviewModels) } + { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) } }; private static IDictionary ExpectedDeliveryMappings => new Dictionary @@ -120,20 +119,6 @@ public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); } - [Fact] - public void GetSwitchMappings_ExtendedDeliveryPreviewIsTrue_ReturnsManagementMappings() - { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-r", - "true" - }); - - result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); - } - [Fact] public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagementMappings() { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs index c601c803..b84fc11f 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs @@ -66,18 +66,15 @@ public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_NoCustomPartialP AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, ClassCodeGenerator.DefaultNamespace); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_NoCustomPartialProperty_Returns(bool extendedDeliverPreviewModels) + [Fact] + public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_NoCustomPartialProperty_Returns() { var classDefinitionCodename = "codename"; var classFileName = "classFileName"; var codeGeneratorOptions = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); @@ -136,10 +133,8 @@ public void CreateClassCodeGenerator_DeliveryClassCodeGenerator_CustomNamespace_ AssertClassCodeGenerator(result, classDefinitionCodename, classFileName, customNamespace); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_CustomNamespace_Returns(bool extendedDeliverPreviewModels) + [Fact] + public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_CustomNamespace_Returns() { var classDefinitionCodename = "codename"; var classFileName = "classFileName"; @@ -148,8 +143,7 @@ public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_CustomNa { ManagementApi = false, Namespace = customNamespace, - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index 269fad38..2badaada 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -12,8 +12,7 @@ public void ManagementApi_ManagementApi_ReturnsTrue() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.ManagementApi(); @@ -22,17 +21,14 @@ public void ManagementApi_ManagementApi_ReturnsTrue() } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [InlineData(true)] + [InlineData(false)] + public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels) { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = extendedDeliverModels }; var result = options.ManagementApi(); @@ -41,16 +37,14 @@ public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverMode } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [InlineData(true)] + [InlineData(false)] + public void ManagementApi_InvalidConfig_ReturnsFalse(bool managementApi) { var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = options.ManagementApi(); @@ -59,17 +53,14 @@ public void ManagementApi_InvalidConfig_ReturnsFalse(bool extendedDeliverModels, } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [InlineData(true)] + [InlineData(false)] + public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extendedDeliverModels) { var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = extendedDeliverModels }; var result = options.ExtendedDeliveryModels(); @@ -78,13 +69,12 @@ public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extende } [Fact] - public void ExtendedDeliveryModels_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsFalse() + public void ExtendedDeliveryModels_ManagementApiIsFalse_ExtendedDeliveryOptionsIsFalse_ReturnsFalse() { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.ExtendedDeliveryModels(); @@ -92,17 +82,13 @@ public void ExtendedDeliveryModels_ManagementApiIsFalse_ExtendedDeliveryOptionsA result.Should().BeFalse(); } - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - public void ExtendedDeliveryModels_ManagementApiIsFalse_ReturnsTrue(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [Fact] + public void ExtendedDeliveryModels_ManagementApiIsFalse_ReturnsTrue() { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = options.ExtendedDeliveryModels(); @@ -121,13 +107,12 @@ public void DeliveryApi_DefaultOptions_ReturnsTrue() } [Fact] - public void DeliveryApi_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsTrue() + public void DeliveryApi_ManagementApiIsFalse_ExtendedDeliveryOptionsIsFalse_ReturnsTrue() { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.DeliveryApi(); @@ -141,8 +126,7 @@ public void DeliveryApi_ManagementApi_ReturnsFalse() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.DeliveryApi(); @@ -150,17 +134,13 @@ public void DeliveryApi_ManagementApi_ReturnsFalse() result.Should().BeFalse(); } - [Theory] - [InlineData(true, true)] - [InlineData(false, true)] - [InlineData(true, false)] - public void DeliveryApi_ExtendedDeliveryOptions_ReturnsFalse(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [Fact] + public void DeliveryApi_ExtendedDeliveryOptions_ReturnsFalse() { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = options.DeliveryApi(); @@ -169,13 +149,12 @@ public void DeliveryApi_ExtendedDeliveryOptions_ReturnsFalse(bool extendedDelive } [Fact] - public void DeliveryApi_ManagementApiIsTrue_ExtendedDeliveryOptionsAreTrue_ReturnsTrue() + public void DeliveryApi_ManagementApiIsTrue_ExtendedDeliveryOptionsIsTrue_ReturnsTrue() { var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = true + ExtendedDeliverModels = true }; var result = options.DeliveryApi(); @@ -189,8 +168,7 @@ public void GetDesiredModelsType_ManagementApi_ReturnsManagement() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.GetDesiredModelsType(); @@ -198,17 +176,13 @@ public void GetDesiredModelsType_ManagementApi_ReturnsManagement() result.Should().Be(DesiredModelsType.Management); } - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - public void GetDesiredModelsType_ExtendedDeliveryModels_ReturnsExtendedDelivery(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [Fact] + public void GetDesiredModelsType_ExtendedDeliveryModels_ReturnsExtendedDelivery() { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }; var result = options.GetDesiredModelsType(); @@ -217,13 +191,12 @@ public void GetDesiredModelsType_ExtendedDeliveryModels_ReturnsExtendedDelivery( } [Fact] - public void GetDesiredModelsType_ManagementApiIsFalse_ExtendedDeliveryOptionsAreFalse_ReturnsDelivery() + public void GetDesiredModelsType_ManagementApiIsFalse_ExtendedDeliveryOptionsIsFalse_ReturnsDelivery() { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }; var result = options.GetDesiredModelsType(); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index 3202b30e..28caeedf 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -59,25 +59,20 @@ public void Constructor_ExtendedDeliverModelsIsFalse_Throws() mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }); Creator(mockOptions.Object).Should().Throw(); } - [Theory] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public void Constructor_CreatesInstance(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [Fact] + public void Constructor_CreatesInstance() { var mockOptions = new Mock>(); mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ExtendedDeliverModels = true }); var extendedDeliveryCodeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); @@ -92,8 +87,7 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = true }); var contentType = new ContentTypeModel @@ -181,81 +175,7 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() } [Fact] - public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsTrue_Returns() - { - var mockOptions = new Mock>(); - mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions - { - ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = true - }); - - var contentType = new ContentTypeModel - { - Codename = "content_type", - Elements = new List - { - LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, - LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, - LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, - LinkedItemsContentTypeData.MultiAllowedTypesMultiItems - } - }; - - var contentTypes = new List { contentType, LinkedItemsContentTypeData.ArticleContentType, LinkedItemsContentTypeData.HeroContentType }; - - var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); - - var result = codeGenerator.GetClassCodeGenerators(contentType, new List(), contentTypes).ToList(); - - var expectedTypedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); - expectedTypedExtendedDeliveryClassDefinition.Properties.AddRange(new List - { - Property.FromContentTypeElement( - LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, - $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", - "ModularContentHeroes_Hero"), - Property.FromContentTypeElement( - LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, - $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>", - "modular_content_article") - }); - expectedTypedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List - { - "ModularContentHeroes_Hero", - "modular_content_article" - }); - - var expectedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); - expectedExtendedDeliveryClassDefinition.Properties.AddRange(new List - { - Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType) - }); - expectedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List - { - "modular_content_heroes", - "modular_content_article", - "modular_content_blog", - "modular_content_coffees" - }); - - var expected = new List - { - new TypedExtendedDeliveryClassCodeGenerator(expectedTypedExtendedDeliveryClassDefinition, "ContentType.Typed.Generated"), - new ExtendedDeliveryClassCodeGenerator(expectedExtendedDeliveryClassDefinition, "ContentType.Generated") - }; - - result.Should().BeEquivalentTo(expected); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task IntegrationTest_RunAsync_CorrectFiles(bool extendedDeliverPreviewModels) + public async Task IntegrationTest_RunAsync_CorrectFiles() { var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions @@ -267,8 +187,7 @@ public async Task IntegrationTest_RunAsync_CorrectFiles(bool extendedDeliverPrev GeneratePartials = false, WithTypeProvider = false, StructuredModel = false, - ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId } }); var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); @@ -284,10 +203,8 @@ public async Task IntegrationTest_RunAsync_CorrectFiles(bool extendedDeliverPrev Directory.Delete(TempDir, true); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(bool extendedDeliverPreviewModels) + [Fact] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() { const string transformFilename = "CustomSuffix"; var mockOptions = new Mock>(); @@ -301,8 +218,7 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(bool ext WithTypeProvider = false, StructuredModel = false, ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, - FileNameSuffix = transformFilename, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + FileNameSuffix = transformFilename }); var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); @@ -320,10 +236,8 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(bool ext Directory.Delete(TempDir, true); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(bool extendedDeliverPreviewModels) + [Fact] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() { const string transformFilename = "Generated"; var mockOptions = new Mock>(); @@ -337,8 +251,7 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(bool ex WithTypeProvider = false, StructuredModel = false, ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, - FileNameSuffix = transformFilename, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels + FileNameSuffix = transformFilename }); var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); @@ -372,10 +285,8 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(bool ex Directory.Delete(TempDir, true); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(bool extendedDeliverPreviewModels) + [Fact] + public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() { var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions @@ -388,7 +299,6 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(bool extend WithTypeProvider = true, StructuredModel = false, ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels }); var codeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, new FileSystemOutputProvider(mockOptions.Object), _managementClient); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 25fd4aa3..5c16dbfe 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -16,14 +16,7 @@ public class TypedDeliveryPropertyMapperTests { private static readonly CodeGeneratorOptions ExtendedDeliverModelsOptions = new CodeGeneratorOptions { - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = false - }; - - private static readonly CodeGeneratorOptions ExtendedDeliverPreviewModelsOptions = new CodeGeneratorOptions - { - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = true + ExtendedDeliverModels = true }; [Fact] @@ -33,13 +26,8 @@ public void TryMap_ElementIsNull_Throws() { new ContentTypeModel() }; - var options = new CodeGeneratorOptions - { - ExtendedDeliverPreviewModels = false, - ExtendedDeliverModels = true - }; - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, options, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, ExtendedDeliverModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -52,13 +40,8 @@ public void TryMap_NotLinkedItemsElementOrSubpages_Throws() new ContentTypeModel() }; var element = new AssetElementMetadataModel(); - var options = new CodeGeneratorOptions - { - ExtendedDeliverPreviewModels = false, - ExtendedDeliverModels = true - }; - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, ExtendedDeliverModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -67,13 +50,7 @@ public void TryMap_NotLinkedItemsElementOrSubpages_Throws() [MemberData(nameof(GetBasicAllowedElements))] public void TryMap_ContentTypesIsNull_Throws(ElementMetadataBase element) { - var options = new CodeGeneratorOptions - { - ExtendedDeliverPreviewModels = false, - ExtendedDeliverModels = true - }; - - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, null, options, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, null, ExtendedDeliverModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -83,13 +60,8 @@ public void TryMap_ContentTypesIsNull_Throws(ElementMetadataBase element) public void TryMap_ContentTypesIsEmpty_Throws(ElementMetadataBase element) { var contentTypes = new List(); - var options = new CodeGeneratorOptions - { - ExtendedDeliverPreviewModels = false, - ExtendedDeliverModels = true - }; - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, ExtendedDeliverModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -118,7 +90,6 @@ public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws(ElementMetadataBa }; var options = new CodeGeneratorOptions { - ExtendedDeliverPreviewModels = false, ExtendedDeliverModels = false }; @@ -127,8 +98,6 @@ public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws(ElementMetadataBa tryMapCall.Should().ThrowExactly(); } - #region Live models - [Theory] [MemberData(nameof(GetNonMatchingAllowedTypesElements))] public void TryMap_Live_CouldNotFindAllowedType_Throws(ElementMetadataBase element) @@ -255,146 +224,6 @@ public void TryMap_Live_MultiAllowedTypesMultiItems_Returns(List() - { - new ContentTypeModel - { - Codename = "article", - Id = Guid.NewGuid() - } - }; - - var allContentTypes = new List() - { - new ContentTypeModel - { - Codename = "grinder", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "coffee", - Id = Guid.NewGuid() - } - }; - - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out _); - - tryMapCall.Should().ThrowExactly(); - } - - [Theory] - [MemberData(nameof(GetSingleAllowedTypeMultiItems))] - public void TryMap_Preview_SingleAllowedTypeMultiItems_Returns(List linkedContentTypeModels, ElementMetadataBase element) - { - var allContentTypes = new List() - { - new ContentTypeModel - { - Codename = "grinder", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "coffee", - Id = Guid.NewGuid() - } - }.Union(linkedContentTypeModels).ToList(); - - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - - result.Should().BeTrue(); - typedProperty.Codename.Should().Be("Articles_Article"); - typedProperty.Id.Should().BeNull(); - typedProperty.Identifier.Should().Be("ArticlesArticle"); - typedProperty.TypeName.Should().Be($"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>"); - } - - [Theory] - [MemberData(nameof(GetSingleAllowedTypeExactlySingleItem))] - public void TryMap_Preview_SingleAllowedTypeExactlySingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) - { - var allContentTypes = new List() - { - new ContentTypeModel - { - Codename = "grinder", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "coffee", - Id = Guid.NewGuid() - } - }.Union(linkedContentTypeModels).ToList(); - - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - - result.Should().BeTrue(); - typedProperty.Codename.Should().Be("article"); - typedProperty.Id.Should().BeNull(); - typedProperty.Identifier.Should().Be("Article"); - typedProperty.TypeName.Should().Be("IEnumerable"); - } - - [Theory] - [MemberData(nameof(GetMultiAllowedTypesSingleItem))] - public void TryMap_Preview_MultiAllowedTypesSingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) - { - var allContentTypes = new List() - { - new ContentTypeModel - { - Codename = "grinder", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "coffee", - Id = Guid.NewGuid() - } - }.Union(linkedContentTypeModels).ToList(); - - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - - result.Should().BeFalse(); - typedProperty.Should().BeNull(); - } - - [Theory] - [MemberData(nameof(GetMultiAllowedTypesMultiItems))] - public void TryMap_Preview_MultiAllowedTypesMultiItems_Returns(List linkedContentTypeModels, ElementMetadataBase element) - { - var allContentTypes = new List() - { - new ContentTypeModel - { - Codename = "grinder", - Id = Guid.NewGuid() - }, - new ContentTypeModel - { - Codename = "coffee", - Id = Guid.NewGuid() - } - }.Union(linkedContentTypeModels).ToList(); - - var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverPreviewModelsOptions, out var typedProperty); - - result.Should().BeFalse(); - typedProperty.Should().BeNull(); - } - - #endregion - public static IEnumerable GetBasicAllowedElements() { yield return new object[] { new LinkedItemsElementMetadataModel() }; diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs index 94465bc1..2485d6b7 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ValidationExtensionsTests.cs @@ -48,17 +48,14 @@ public void Validate_DeliveryOptions_DoesNotThrow() validateCall.Should().NotThrow(); } - [Theory] - [InlineData(true, false)] - [InlineData(false, true)] - public void Validate_ExtendedDeliveryModels_DoesNotThrow(bool extendedDeliverModels, bool extendedDeliverPreviewModels) + [Fact] + public void Validate_ExtendedDeliveryModels_DoesNotThrow() { var projectId = Guid.NewGuid().ToString(); var codeGeneratorOptions = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels, - ExtendedDeliverPreviewModels = extendedDeliverPreviewModels, + ExtendedDeliverModels = true, ManagementOptions = new ManagementOptions { ProjectId = projectId, @@ -171,8 +168,7 @@ public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException( new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }, "Management", "https://bit.ly/3rSMeDA" @@ -182,23 +178,10 @@ public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException( new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = false - }, - "Delivery", - "https://bit.ly/3rSMeDA" - }, - new object[] - { - new CodeGeneratorOptions - { - ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = true + ExtendedDeliverModels = true }, "Delivery", "https://bit.ly/3rSMeDA" - } }; @@ -209,8 +192,7 @@ public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException( new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = false }, null, "Management", @@ -221,25 +203,11 @@ public void Validate_ApiKeyIsNullOrWhiteSpace_ThrowsException( new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true, - ExtendedDeliverPreviewModels = false + ExtendedDeliverModels = true }, "", "Delivery", "https://bit.ly/3rSMeDA" - }, - new object[] - { - new CodeGeneratorOptions - { - ManagementApi = false, - ExtendedDeliverModels = false, - ExtendedDeliverPreviewModels = true - }, - " ", - "Delivery", - "https://bit.ly/3rSMeDA" - } }; } From 396ba3f647f9a969b153acf4eacc953a85db052b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 16 Feb 2023 15:31:54 +0100 Subject: [PATCH 31/48] 90 intruduce structured datetime to tests for extended delivery models --- ...ompleteContentType_CompiledCode_ExtendedDeliveryModels.txt | 1 + .../Class/ExtendedDeliveryClassCodeGeneratorTests.cs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt index d3edeea4..37b9441d 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt @@ -19,6 +19,7 @@ namespace KontentAiModels public IEnumerable Asset { get; set; } public string Custom { get; set; } public DateTime? DateTime { get; set; } + public IDateTimeContent DateTimeStructured { get; set; } public IEnumerable ModularContentArticle { get; set; } public IEnumerable ModularContentBlog { get; set; } public IEnumerable ModularContentCoffees { get; set; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index 210976d4..795cbdf2 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -130,6 +130,10 @@ public ExtendedDeliveryClassCodeGeneratorTests() TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), ElementMetadataType.RichText + Property.StructuredSuffix)); + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a91"), "date_time_structured", ElementMetadataType.DateTime), + ElementMetadataType.DateTime + Property.StructuredSuffix)); + ClassDefinition.AddProperty(Property.FromContentTypeElement( TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy), ElementMetadataType.Taxonomy.ToString())); From 217b1141d9b622c2134258f93a4e2a6cd57321d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 16 Feb 2023 16:30:40 +0100 Subject: [PATCH 32/48] 90 docs --- README.md | 62 +++++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 2705ec8f..abd6fbc2 100644 --- a/README.md +++ b/README.md @@ -102,56 +102,50 @@ namespace KontentAiModels } ``` -#### Extended delivery models -```csharp -using System; -using System.Collections.Generic; -using Kontent.Ai.Delivery.Abstractions; +### Customizing models - Extended delivery models +Provides support to customize generated models based on content linked/subpages element constraints. This feature uses [Management SDK](https://github.com/kontent-ai/management-sdk-net) thus you'll need to provide api key as well. -namespace KontentAiModels +Be aware that the generated models will be implementing the newly generated `IContentItem` interface. +```csharp +public interface IContentItem { - public partial class CompleteContentType - { - public string Text { get; set; } - public string RichText { get; set; } - public IRichTextContent RichTextStructured { get; set; } - public decimal? Number { get; set; } - public IEnumerable MultipleChoice { get; set; } - public DateTime? DateTime { get; set; } - public IEnumerable Asset { get; set; } - public IEnumerable ModularContent { get; set; } - public IEnumerable Subpages { get; set; } - public IEnumerable Taxonomy { get; set; } - public string UrlSlug { get; set; } - public string CustomElement { get; set; } - public ContentItemSystemAttributes System { get; set; } - } + public IContentItemSystemAttributes System { get; set; } } ``` -### Customizing models - Handling content element constraints - -Currently, the generator is built on top of the Delivery API which doesn't provide information about content element constraints such as "Allowed Content Types" or "Limit number of items". In case you want your models to be more specific, this is the best practice on how to extend them: - +#### Extended delivery models example output Model.Generated.cs ```csharp -public partial class Home +public partial class Home : IContentItem { - public IEnumerable LinkedContentItems { get; set; } + public const string SingleAllowedTypeSingleLinkedContentItemCodename = "single_allowed_type_single_linked_content_item"; + public const string SingleAllowedTypeMultiLinkedContentItemsCodename = "single_allowed_type_multi_linked_content_items"; + public const string MultiAllowedTypesSingleLinkedContentItemCodename = "multi_allowed_types_single_linked_content_item"; + public const string MultiAllowedTypesMultiLinkedContentItemsCodename = "multi_allowed_types_multi_linked_content_items"; + + // Allowed Content Types == "Article" && Limit number of items == 1 + public IEnumerable SingleAllowedTypeSingleLinkedContentItem { get; set; } + + // Allowed Content Types == "Article" && Limit number of items > 1 + public IEnumerable SingleAllowedTypeMultiLinkedContentItems { get; set; } + + // Allowed Content Types number > 1 && Limit number of items == 1 + public IEnumerable MultiAllowedTypesSingleLinkedContentItem { get; set; } + + // Allowed Content Types number > 1 && Limit number of items > 1 + public IEnumerable MultiAllowedTypesMultiLinkedContentItems { get; set; } } ``` -Model.cs +Model.Typed.Generated.cs ```csharp public partial class Home { - // Allowed Content Types == "Article" - public IEnumerable
Articles => LinkedContentItems.OfType
(); - - // Allowed Content Types == "Article" && Limit number of items == 1 - public Article Article => LinkedContentItems.OfType
().FirstOrDefault(); + public Article SingleAllowedTypeSingleLinkedContentItemSingle => SingleAllowedTypeSingleLinkedContentItem.OfType
().FirstOrDefault(); + + public IEnumerable
SingleAllowedTypeMultiLinkedContentItemsArticleTyped => SingleAllowedTypeMultiLinkedContentItems.OfType
(); } ``` From 4f85cede12961c5bde8e72a335f9bf6e020dedb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 2 Mar 2023 13:29:04 +0100 Subject: [PATCH 33/48] 90 introduce structured modular content option --- .../CodeGeneratorBase.cs | 4 +- .../Common/ClassCodeGeneratorFactory.cs | 2 +- .../Common/Property.cs | 10 +- .../CodeGeneratorOptionsExtensions.cs | 10 + .../Configuration/StructuredModelFlags.cs | 3 +- .../ExtendedDeliveryCodeGenerator.cs | 11 +- .../ExtendedDeliveryClassCodeGenerator.cs | 12 +- .../Helpers/DeliveryElementHelper.cs | 4 + .../CompleteContentType_CompiledCode.txt | 1 + ...pe_CompiledCode_ExtendedDeliveryModels.txt | 18 +- ...dModularContent_ExtendedDeliveryModels.txt | 40 ++++ .../CodeGeneratorTestsBase.cs | 9 +- .../Common/PropertyTests.cs | 19 ++ .../CodeGeneratorOptionsExtensionsTests.cs | 103 +++++++++- .../DeliveryCodeGeneratorTests.cs | 35 ++-- .../ExtendedDeliveryCodeGeneratorTests.cs | 91 ++++++--- .../Fixtures/ManagementModelsProvider.cs | 10 +- .../Class/DeliveryClassCodeGeneratorTests.cs | 10 +- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 190 ++++++++++-------- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 8 +- .../Helpers/DeliveryElementHelperTests.cs | 9 +- .../Kontent.Ai.ModelGenerator.Tests.csproj | 4 + 22 files changed, 431 insertions(+), 172 deletions(-) create mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt diff --git a/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs index fe23fb77..a2a72b75 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/CodeGeneratorBase.cs @@ -11,14 +11,12 @@ namespace Kontent.Ai.ModelGenerator.Core; public abstract class CodeGeneratorBase { - private string ProjectId => Options.ManagementApi ? Options.ManagementOptions.ProjectId : Options.DeliveryOptions.ProjectId; - protected readonly CodeGeneratorOptions Options; protected readonly IOutputProvider OutputProvider; protected string FilenameSuffix => string.IsNullOrEmpty(Options.FileNameSuffix) ? "" : $".{Options.FileNameSuffix}"; protected string NoContentTypeAvailableMessage => - $@"No content type available for the project ({ProjectId}). Please make sure you have the Delivery API enabled at https://app.kontent.ai/."; + $@"No content type available for the project ({Options.GetProjectId()}). Please make sure you have the Delivery API enabled at https://app.kontent.ai/."; protected CodeGeneratorBase(IOptions options, IOutputProvider outputProvider) { diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs index 4b4ddb18..d0c7da09 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/ClassCodeGeneratorFactory.cs @@ -34,7 +34,7 @@ public static ClassCodeGenerator CreateClassCodeGenerator(CodeGeneratorOptions o } return options.ExtendedDeliveryModels() - ? new ExtendedDeliveryClassCodeGenerator(classDefinition, classFilename, options.Namespace) + ? new ExtendedDeliveryClassCodeGenerator(classDefinition, classFilename, options.IsStructuredModelModularContent(), options.Namespace) : new DeliveryClassCodeGenerator(classDefinition, classFilename, options.Namespace); } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 069dfed0..1f28f5b3 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -5,6 +5,7 @@ using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management.Models.LanguageVariants.Elements; using Kontent.Ai.Management.Models.Types.Elements; +using Kontent.Ai.ModelGenerator.Core.Generators.Class; using Kontent.Ai.ModelGenerator.Core.Helpers; namespace Kontent.Ai.ModelGenerator.Core.Common; @@ -13,8 +14,12 @@ public class Property { private const string RichTextElementType = "rich_text"; private const string DateTimeElementType = "date_time"; + private const string ModularContentElementType = "modular_content"; + public const string StructuredSuffix = "(structured)"; + public static string ObjectType => nameof(Object).ToLower(CultureInfo.InvariantCulture); + public string Identifier => TextHelpers.GetValidPascalCaseIdentifierName(Codename); public string Codename { get; } @@ -36,7 +41,8 @@ public class Property { $"{DateTimeElementType}{StructuredSuffix}", nameof(IDateTimeContent) }, { "multiple_choice", TextHelpers.GetEnumerableType(nameof(IMultipleChoiceOption))}, { "asset", TextHelpers.GetEnumerableType(nameof(IAsset)) }, - { "modular_content", TextHelpers.GetEnumerableType(nameof(Object).ToLower(CultureInfo.InvariantCulture)) }, + { ModularContentElementType, TextHelpers.GetEnumerableType(ObjectType) }, + { $"{ModularContentElementType}{StructuredSuffix}", TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName) }, { "taxonomy", TextHelpers.GetEnumerableType(nameof(ITaxonomyTerm)) }, { "url_slug", "string" }, { "custom", "string" } @@ -85,6 +91,8 @@ public Property(string codename, string typeName, string id = null) public static bool IsRichTextElementType(string elementType) => elementType == RichTextElementType; + public static bool IsModularContentElementType(string elementType) => elementType == ModularContentElementType; + public static bool IsContentTypeSupported(string elementType, bool extendedDeliverModels) => extendedDeliverModels ? ExtendedDeliverElementTypesDictionary.ContainsKey(elementType) : DeliverElementTypesDictionary.ContainsKey(elementType); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index 3f6e1812..f485a940 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -19,9 +19,19 @@ public static DesiredModelsType GetDesiredModelsType(this CodeGeneratorOptions o return options.ExtendedDeliveryModels() ? DesiredModelsType.ExtendedDelivery : DesiredModelsType.Delivery; } + + public static string GetProjectId(this CodeGeneratorOptions options) => + options.ManagementApi || options.ExtendedDeliverModels + ? options.ManagementOptions.ProjectId + : options.DeliveryOptions.ProjectId; + + public static bool IsStructuredModelModularContent(this CodeGeneratorOptions options) => + options.StructuredModelFlags.HasFlag(StructuredModelFlags.ModularContent); + public static bool IsStructuredModelEnabled(this CodeGeneratorOptions options) => options.StructuredModelFlags.HasFlag(StructuredModelFlags.RichText) || options.StructuredModelFlags.HasFlag(StructuredModelFlags.True) || + options.StructuredModelFlags.HasFlag(StructuredModelFlags.ModularContent) || options.StructuredModelFlags.HasFlag(StructuredModelFlags.DateTime); public static bool IsStructuredModelRichText(this CodeGeneratorOptions options) => diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/StructuredModelFlags.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/StructuredModelFlags.cs index 792bb813..42c2fd5d 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/StructuredModelFlags.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/StructuredModelFlags.cs @@ -9,5 +9,6 @@ public enum StructuredModelFlags RichText = 2, DateTime = 4, ValidationIssue = 8, - True = 16 + True = 16, + ModularContent = 32 } diff --git a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs index f6bcb182..9ce30f9a 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs @@ -45,7 +45,10 @@ protected override async Task> GetClassCodeGener return codeGenerators; } - codeGenerators.Add(new ContentItemClassCodeGenerator(Options.Namespace)); + if (Options.IsStructuredModelModularContent()) + { + codeGenerators.Add(new ContentItemClassCodeGenerator(Options.Namespace)); + } foreach (var contentType in deliveryTypes) { @@ -112,7 +115,11 @@ private void AddProperty(ElementMetadataBase el, ref ClassDefinition classDefini AddProperty(typedProperty, ref typedClassDefinition); } - elementType = TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName); + var linkedObjectType = Options.IsStructuredModelModularContent() + ? ContentItemClassCodeGenerator.DefaultContentItemClassName + : Property.ObjectType; + + elementType = TextHelpers.GetEnumerableType(linkedObjectType); } var property = Property.FromContentTypeElement(el, elementType!); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs index 6907ad98..04ff9171 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs @@ -6,9 +6,12 @@ namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; public class ExtendedDeliveryClassCodeGenerator : DeliveryClassCodeGenerator { - public ExtendedDeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, string @namespace = DefaultNamespace) + private readonly bool _generateStructuredModularContent; + + public ExtendedDeliveryClassCodeGenerator(ClassDefinition classDefinition, string classFilename, bool generateStructuredModularContent, string @namespace = DefaultNamespace) : base(classDefinition, classFilename, @namespace) { + _generateStructuredModularContent = generateStructuredModularContent; } protected override TypeDeclarationSyntax GetClassDeclaration() @@ -17,8 +20,11 @@ protected override TypeDeclarationSyntax GetClassDeclaration() var classDeclaration = base.GetClassDeclaration(); - var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(ContentItemClassCodeGenerator.DefaultContentItemClassName)); - classDeclaration = (TypeDeclarationSyntax)classDeclaration.AddBaseListTypes(baseType); + if (_generateStructuredModularContent) + { + var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(ContentItemClassCodeGenerator.DefaultContentItemClassName)); + classDeclaration = (TypeDeclarationSyntax)classDeclaration.AddBaseListTypes(baseType); + } return classDeclaration; } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs index 1c80f389..d18e5d9f 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs @@ -23,6 +23,10 @@ public static string GetElementType(CodeGeneratorOptions options, string element { elementType += Property.StructuredSuffix; } + else if (!options.ExtendedDeliverModels && options.IsStructuredModelModularContent() && Property.IsModularContentElementType(elementType)) + { + elementType += Property.StructuredSuffix; + } return elementType; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode.txt index 063b3d51..ec7c4ca2 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode.txt @@ -21,6 +21,7 @@ namespace KontentAiModels public DateTime? DateTime { get; set; } public IDateTimeContent DateTimeStructured { get; set; } public IEnumerable ModularContent { get; set; } + public IEnumerable ModularContentStructured { get; set; } public IEnumerable MultipleChoice { get; set; } public decimal? Number { get; set; } public string RichText { get; set; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt index 37b9441d..067ceabb 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt @@ -12,7 +12,7 @@ using Kontent.Ai.Delivery.Abstractions; namespace KontentAiModels { - public partial class CompleteContentType : IContentItem + public partial class CompleteContentType { public const string Codename = "Complete content type"; @@ -20,18 +20,18 @@ namespace KontentAiModels public string Custom { get; set; } public DateTime? DateTime { get; set; } public IDateTimeContent DateTimeStructured { get; set; } - public IEnumerable ModularContentArticle { get; set; } - public IEnumerable ModularContentBlog { get; set; } - public IEnumerable ModularContentCoffees { get; set; } - public IEnumerable ModularContentHeroes { get; set; } + public IEnumerable ModularContentArticle { get; set; } + public IEnumerable ModularContentBlog { get; set; } + public IEnumerable ModularContentCoffees { get; set; } + public IEnumerable ModularContentHeroes { get; set; } public IEnumerable MultipleChoice { get; set; } public decimal? Number { get; set; } public string RichText { get; set; } public IRichTextContent RichTextStructured { get; set; } - public IEnumerable SubpagesArticle { get; set; } - public IEnumerable SubpagesBlog { get; set; } - public IEnumerable SubpagesCoffees { get; set; } - public IEnumerable SubpagesHeroes { get; set; } + public IEnumerable SubpagesArticle { get; set; } + public IEnumerable SubpagesBlog { get; set; } + public IEnumerable SubpagesCoffees { get; set; } + public IEnumerable SubpagesHeroes { get; set; } public IContentItemSystemAttributes System { get; set; } public IEnumerable Taxonomy { get; set; } public string Text { get; set; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt new file mode 100644 index 00000000..37b9441d --- /dev/null +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt @@ -0,0 +1,40 @@ +// +// This code was generated by a kontent-generators-net tool +// (see https://github.com/kontent-ai/model-generator-net). +// +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// For further modifications of the class, create a separate file with the partial class. +// + +using System; +using System.Collections.Generic; +using Kontent.Ai.Delivery.Abstractions; + +namespace KontentAiModels +{ + public partial class CompleteContentType : IContentItem + { + public const string Codename = "Complete content type"; + + public IEnumerable Asset { get; set; } + public string Custom { get; set; } + public DateTime? DateTime { get; set; } + public IDateTimeContent DateTimeStructured { get; set; } + public IEnumerable ModularContentArticle { get; set; } + public IEnumerable ModularContentBlog { get; set; } + public IEnumerable ModularContentCoffees { get; set; } + public IEnumerable ModularContentHeroes { get; set; } + public IEnumerable MultipleChoice { get; set; } + public decimal? Number { get; set; } + public string RichText { get; set; } + public IRichTextContent RichTextStructured { get; set; } + public IEnumerable SubpagesArticle { get; set; } + public IEnumerable SubpagesBlog { get; set; } + public IEnumerable SubpagesCoffees { get; set; } + public IEnumerable SubpagesHeroes { get; set; } + public IContentItemSystemAttributes System { get; set; } + public IEnumerable Taxonomy { get; set; } + public string Text { get; set; } + public string UrlSlug { get; set; } + } +} \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs b/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs index d64016b1..546fb099 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/CodeGeneratorTestsBase.cs @@ -6,7 +6,6 @@ using Moq; using System.Collections.Generic; using System.IO; -using System.Threading.Tasks; namespace Kontent.Ai.ModelGenerator.Tests; @@ -33,17 +32,17 @@ protected static IManagementClient CreateManagementClient() var contentTypeListingResponseModel = new Mock>(); contentTypeListingResponseModel.As>() .Setup(c => c.GetEnumerator()) - .Returns(() => managementModelsProvider.ManagementContentTypeModels); + .Returns(managementModelsProvider.ManagementContentTypeModels.GetEnumerator); var contentTypeSnippetListingResponseModel = new Mock>(); contentTypeSnippetListingResponseModel.As>() .Setup(c => c.GetEnumerator()) - .Returns(() => managementModelsProvider.ManagementContentTypeSnippetModels); + .Returns(managementModelsProvider.ManagementContentTypeSnippetModels.GetEnumerator); managementClientMock.Setup(client => client.ListContentTypeSnippetsAsync()) - .Returns(Task.FromResult(contentTypeSnippetListingResponseModel.Object)); + .ReturnsAsync(() => contentTypeSnippetListingResponseModel.Object); managementClientMock.Setup(client => client.ListContentTypesAsync()) - .Returns(Task.FromResult(contentTypeListingResponseModel.Object)); + .ReturnsAsync(() => contentTypeListingResponseModel.Object); return managementClientMock.Object; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs index 29c8600a..2567f4b2 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/PropertyTests.cs @@ -44,6 +44,7 @@ public void Constructor_IdParamPresent_ObjectIsInitializedWithCorrectValues(stri [InlineData($"date_time{Property.StructuredSuffix}", "IDateTimeContent")] [InlineData("asset", "IEnumerable")] [InlineData("modular_content", "IEnumerable")] + [InlineData($"modular_content{Property.StructuredSuffix}", "IEnumerable")] [InlineData("taxonomy", "IEnumerable")] [InlineData("url_slug", "string")] [InlineData("custom", "string")] @@ -143,6 +144,24 @@ public void IsRichTextElementType_ReturnsTrue() result.Should().BeTrue(); } + [Theory] + [InlineData("text")] + [InlineData("modular_content(structured)")] + public void IsModularContentElementType_NotModularContentElementType_ReturnsFalse(string elementType) + { + var result = Property.IsModularContentElementType(elementType); + + result.Should().BeFalse(); + } + + [Fact] + public void IsModularContentElementType_ReturnsTrue() + { + var result = Property.IsModularContentElementType("modular_content"); + + result.Should().BeTrue(); + } + public static IEnumerable ManagementElements => new List<(string, string, ElementMetadataBase)> { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index ac2fed7d..4baa523e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -1,4 +1,7 @@ -using FluentAssertions; +using System; +using FluentAssertions; +using Kontent.Ai.Delivery.Abstractions; +using Kontent.Ai.Management.Configuration; using Kontent.Ai.ModelGenerator.Core.Configuration; using Xunit; @@ -7,13 +10,15 @@ namespace Kontent.Ai.ModelGenerator.Tests.Configuration; public class CodeGeneratorOptionsExtensionsTests { [Theory] + [InlineData(StructuredModelFlags.ModularContent)] [InlineData(StructuredModelFlags.DateTime)] [InlineData(StructuredModelFlags.RichText)] [InlineData(StructuredModelFlags.True)] [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime)] [InlineData(StructuredModelFlags.True | StructuredModelFlags.DateTime)] [InlineData(StructuredModelFlags.True | StructuredModelFlags.RichText)] - [InlineData(StructuredModelFlags.True | StructuredModelFlags.RichText | StructuredModelFlags.DateTime)] + [InlineData(StructuredModelFlags.True | StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.True | StructuredModelFlags.RichText | StructuredModelFlags.DateTime | StructuredModelFlags.ModularContent)] public void IsStructuredModelEnabled_Enabled_ReturnsTrue(StructuredModelFlags structuredModel) { var options = new CodeGeneratorOptions @@ -54,6 +59,37 @@ public void IsStructuredModelEnabled_Disabled_InvalidString_ReturnsFalse() result.Should().BeFalse(); } + + [Fact] + public void IsStructuredModelModularContent_Enabled_ReturnsTrue() + { + var options = new CodeGeneratorOptions + { + StructuredModel = StructuredModelFlags.ModularContent.ToString() + }; + + var result = options.IsStructuredModelModularContent(); + + result.Should().BeTrue(); + } + + [Theory] + [InlineData(StructuredModelFlags.DateTime)] + [InlineData(StructuredModelFlags.ValidationIssue)] + [InlineData(StructuredModelFlags.RichText)] + [InlineData(StructuredModelFlags.NotSet)] + public void IsStructuredModelModularContent_Disabled_ReturnsFalse(StructuredModelFlags structuredModel) + { + var options = new CodeGeneratorOptions + { + StructuredModel = structuredModel.ToString() + }; + + var result = options.IsStructuredModelModularContent(); + + result.Should().BeFalse(); + } + [Theory] [InlineData(StructuredModelFlags.True)] [InlineData(StructuredModelFlags.RichText)] @@ -71,10 +107,11 @@ public void IsStructuredModelRichText_Enabled_ReturnsTrue(StructuredModelFlags s } [Theory] + [InlineData(StructuredModelFlags.ModularContent)] [InlineData(StructuredModelFlags.DateTime)] [InlineData(StructuredModelFlags.ValidationIssue)] [InlineData(StructuredModelFlags.NotSet)] - public void IsStructuredModelRichText_Disabled_ReturnsTrue(StructuredModelFlags structuredModel) + public void IsStructuredModelRichText_Disabled_ReturnsFalse(StructuredModelFlags structuredModel) { var options = new CodeGeneratorOptions { @@ -306,4 +343,64 @@ public void GetDesiredModelsType_DefaultOptions_ReturnsDelivery() result.Should().Be(DesiredModelsType.Delivery); } + + [Fact] + public void GetProjectId_DeliveryApi_Returns() + { + var projectId = Guid.NewGuid().ToString(); + + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = false, + DeliveryOptions = new DeliveryOptions + { + ProjectId = projectId + } + }; + + var result = options.GetProjectId(); + + result.Should().Be(projectId); + } + + [Fact] + public void GetProjectId_ManagementApi_Returns() + { + var projectId = Guid.NewGuid().ToString(); + + var options = new CodeGeneratorOptions + { + ManagementApi = true, + ExtendedDeliverModels = false, + ManagementOptions = new ManagementOptions + { + ProjectId = projectId + } + }; + + var result = options.GetProjectId(); + + result.Should().Be(projectId); + } + + [Fact] + public void GetProjectId_ExtendedDeliveryModels_Returns() + { + var projectId = Guid.NewGuid().ToString(); + + var options = new CodeGeneratorOptions + { + ManagementApi = false, + ExtendedDeliverModels = true, + ManagementOptions = new ManagementOptions + { + ProjectId = projectId + } + }; + + var result = options.GetProjectId(); + + result.Should().Be(projectId); + } } \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs index 75590f6d..b2696fe8 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/DeliveryCodeGeneratorTests.cs @@ -45,7 +45,8 @@ public void Constructor_ManagementIsTrue_Throws() [InlineData(StructuredModelFlags.DateTime)] [InlineData(StructuredModelFlags.RichText)] [InlineData(StructuredModelFlags.True)] - [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime | StructuredModelFlags.True)] + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime | StructuredModelFlags.True | StructuredModelFlags.ModularContent)] [InlineData(StructuredModelFlags.NotSet)] public void GetClassCodeGenerator_Returns(StructuredModelFlags structuredModel) { @@ -76,8 +77,10 @@ public void GetClassCodeGenerator_Returns(StructuredModelFlags structuredModel) result.ClassFilename.Should().Be($"{contentTypeCodename}.Generated"); } - [Fact] - public async Task IntegrationTest_RunAsync_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags structuredModel) { var mockHttp = new MockHttpMessageHandler(); mockHttp.When("https://deliver.kontent.ai/*") @@ -93,7 +96,7 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() ManagementApi = false, GeneratePartials = false, WithTypeProvider = false, - StructuredModel = null + StructuredModel = structuredModel.ToString() }); var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); @@ -112,8 +115,10 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() Directory.Delete(TempDir, true); } - [Fact] - public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(StructuredModelFlags structuredModel) { var mockHttp = new MockHttpMessageHandler(); mockHttp.When("https://deliver.kontent.ai/*") @@ -129,7 +134,7 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() Namespace = "CustomNamespace", OutputDir = TempDir, GeneratePartials = false, - StructuredModel = null, + StructuredModel = structuredModel.ToString(), WithTypeProvider = false, FileNameSuffix = transformFilename, ManagementApi = false @@ -152,8 +157,10 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() Directory.Delete(TempDir, true); } - [Fact] - public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(StructuredModelFlags structuredModel) { var mockHttp = new MockHttpMessageHandler(); mockHttp.When("https://deliver.kontent.ai/*") @@ -171,7 +178,7 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() FileNameSuffix = transformFilename, GeneratePartials = true, WithTypeProvider = false, - StructuredModel = null, + StructuredModel = structuredModel.ToString(), ManagementApi = false }); @@ -198,8 +205,10 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() Directory.Delete(TempDir, true); } - [Fact] - public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(StructuredModelFlags structuredModel) { var mockHttp = new MockHttpMessageHandler(); mockHttp.When("https://deliver.kontent.ai/*") @@ -215,7 +224,7 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() ManagementApi = false, GeneratePartials = false, WithTypeProvider = true, - StructuredModel = null + StructuredModel = structuredModel.ToString() }); var deliveryClient = DeliveryClientBuilder.WithProjectId(ProjectId).WithDeliveryHttpClient(new DeliveryHttpClient(httpClient)).Build(); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index e73efd89..b9883c71 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -28,7 +28,6 @@ public class ExtendedDeliveryCodeGeneratorTests : CodeGeneratorTestsBase /// private const int NumberOfContentTypesWithDefaultContentItem = (14 * 2) + 1; - private readonly string DefaultLinkedItemsType = TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName); private readonly IManagementClient _managementClient; private readonly IOutputProvider _outputProvider; protected override string TempDir => Path.Combine(Path.GetTempPath(), "ExtendedDeliveryCodeGeneratorIntegrationTests"); @@ -80,14 +79,17 @@ public void Constructor_CreatesInstance() extendedDeliveryCodeGenerator.Should().NotBeNull(); } - [Fact] - public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() + [Theory] + [InlineData(StructuredModelFlags.ModularContent, true)] + [InlineData(StructuredModelFlags.NotSet, false)] + public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(StructuredModelFlags structuredModel, bool generateStructuredModularContent) { var mockOptions = new Mock>(); mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true + ExtendedDeliverModels = true, + StructuredModel = structuredModel.ToString() }); var contentType = new ContentTypeModel @@ -144,14 +146,14 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() var expectedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); expectedExtendedDeliveryClassDefinition.Properties.AddRange(new List { - Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType), - Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType), - Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType), - Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType) + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType(structuredModel)) }); expectedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List { @@ -168,14 +170,16 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns() var expected = new List { new TypedExtendedDeliveryClassCodeGenerator(expectedTypedExtendedDeliveryClassDefinition, "ContentType.Typed.Generated"), - new ExtendedDeliveryClassCodeGenerator(expectedExtendedDeliveryClassDefinition, "ContentType.Generated") + new ExtendedDeliveryClassCodeGenerator(expectedExtendedDeliveryClassDefinition, "ContentType.Generated", generateStructuredModularContent) }; result.Should().BeEquivalentTo(expected); } - [Fact] - public async Task IntegrationTest_RunAsync_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent, NumberOfContentTypesWithDefaultContentItem)] + [InlineData(StructuredModelFlags.NotSet, NumberOfContentTypesWithDefaultContentItem - 1)] + public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags structuredModel, int expectedNumberOfFiles) { var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions @@ -186,7 +190,7 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() ManagementApi = false, GeneratePartials = false, WithTypeProvider = false, - StructuredModel = StructuredModelFlags.NotSet.ToString(), + StructuredModel = structuredModel.ToString(), ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId } }); @@ -194,7 +198,9 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() await codeGenerator.RunAsync(); - Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem); + AssertPresenceOfIContentItemFile(structuredModel); + + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(expectedNumberOfFiles); Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs").Should().NotBeEmpty(); Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs")).Should().NotBeEmpty(); @@ -203,8 +209,10 @@ public async Task IntegrationTest_RunAsync_CorrectFiles() Directory.Delete(TempDir, true); } - [Fact] - public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent, NumberOfContentTypesWithDefaultContentItem)] + [InlineData(StructuredModelFlags.NotSet, NumberOfContentTypesWithDefaultContentItem - 1)] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(StructuredModelFlags structuredModel, int expectedNumberOfFiles) { const string transformFilename = "CustomSuffix"; var mockOptions = new Mock>(); @@ -216,7 +224,7 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() ManagementApi = false, GeneratePartials = false, WithTypeProvider = false, - StructuredModel = StructuredModelFlags.NotSet.ToString(), + StructuredModel = structuredModel.ToString(), ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, FileNameSuffix = transformFilename }); @@ -225,7 +233,9 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() await codeGenerator.RunAsync(); - Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem); + AssertPresenceOfIContentItemFile(structuredModel); + + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(expectedNumberOfFiles); foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(f => !f.Contains($"{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs"))) { @@ -236,8 +246,10 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles() Directory.Delete(TempDir, true); } - [Fact] - public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent, 1)] + [InlineData(StructuredModelFlags.NotSet, 0)] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(StructuredModelFlags structuredModel, int numberOfExtraGeneratedFiles) { const string transformFilename = "Generated"; var mockOptions = new Mock>(); @@ -249,7 +261,7 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() ManagementApi = false, GeneratePartials = true, WithTypeProvider = false, - StructuredModel = StructuredModelFlags.NotSet.ToString(), + StructuredModel = structuredModel.ToString(), ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, FileNameSuffix = transformFilename }); @@ -260,13 +272,11 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; - var result = generatedCount + (generatedCount / 2) + 1; + var result = generatedCount + (generatedCount / 2) + numberOfExtraGeneratedFiles; result.Should().Be(allFilesCount); - var defaultContentItemClassCodeGeneratorExists = File.Exists(Path.GetFullPath($"{TempDir}//{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs")); - defaultContentItemClassCodeGeneratorExists.Should().BeTrue(); - + AssertPresenceOfIContentItemFile(structuredModel); foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir)) .Where(f => @@ -285,8 +295,10 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles() Directory.Delete(TempDir, true); } - [Fact] - public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() + [Theory] + [InlineData(StructuredModelFlags.ModularContent, NumberOfContentTypesWithDefaultContentItem + 1)] + [InlineData(StructuredModelFlags.NotSet, NumberOfContentTypesWithDefaultContentItem)] + public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(StructuredModelFlags structuredModel, int expectedNumberOfFiles) { var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions @@ -297,7 +309,7 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() ManagementApi = false, GeneratePartials = false, WithTypeProvider = true, - StructuredModel = StructuredModelFlags.NotSet.ToString(), + StructuredModel = structuredModel.ToString(), ManagementOptions = new ManagementOptions { ApiKey = "apiKey", ProjectId = ProjectId }, }); @@ -305,7 +317,9 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() await codeGenerator.RunAsync(); - Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem + 1); + AssertPresenceOfIContentItemFile(structuredModel); + + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(expectedNumberOfFiles); Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs").Should().NotBeEmpty(); @@ -315,4 +329,17 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles() private Func Creator(IOptions options) => () => new ExtendedDeliveryCodeGenerator(options, _outputProvider, _managementClient); + + private string DefaultLinkedItemsType(StructuredModelFlags structuredModel) => + TextHelpers.GetEnumerableType( + structuredModel.HasFlag(StructuredModelFlags.ModularContent) + ? ContentItemClassCodeGenerator.DefaultContentItemClassName + : Property.ObjectType + ); + + private void AssertPresenceOfIContentItemFile(StructuredModelFlags structuredModel) + { + var defaultContentItemClassCodeGeneratorExists = File.Exists(Path.GetFullPath($"{TempDir}//{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs")); + defaultContentItemClassCodeGeneratorExists.Should().Be(structuredModel is StructuredModelFlags.ModularContent); + } } \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs b/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs index 54bb0070..4d863018 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Fixtures/ManagementModelsProvider.cs @@ -10,8 +10,8 @@ namespace Kontent.Ai.ModelGenerator.Tests.Fixtures; internal class ManagementModelsProvider { - public IEnumerator ManagementContentTypeModels { get; } - public IEnumerator ManagementContentTypeSnippetModels { get; } + public IEnumerable ManagementContentTypeModels { get; } + public IEnumerable ManagementContentTypeSnippetModels { get; } public ManagementModelsProvider() { @@ -19,7 +19,7 @@ public ManagementModelsProvider() ManagementContentTypeSnippetModels = GetModels("Fixtures/management_snippets.json"); } - private static IEnumerator GetModels(string filePath) + private static IEnumerable GetModels(string filePath) { var stringServerResponse = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, filePath)); var jTokenServerResponse = JToken.ReadFrom(new JsonTextReader(new StringReader(stringServerResponse))); @@ -31,8 +31,6 @@ private static IEnumerator GetModels(string filePath) _ => throw new NotSupportedException() }; - return jTokenServerResponse[objectTypesProperty] - .ToObject>() - .GetEnumerator(); + return jTokenServerResponse[objectTypesProperty].ToObject>(); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs index 3573612a..04863b4a 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs @@ -23,6 +23,7 @@ public DeliveryClassCodeGeneratorTests() ClassDefinition.AddProperty(Property.FromContentTypeElement("date_time_structured", "date_time(structured)")); ClassDefinition.AddProperty(Property.FromContentTypeElement("asset", "asset")); ClassDefinition.AddProperty(Property.FromContentTypeElement("modular_content", "modular_content")); + ClassDefinition.AddProperty(Property.FromContentTypeElement("modular_content_structured", "modular_content(structured)")); ClassDefinition.AddProperty(Property.FromContentTypeElement("taxonomy", "taxonomy")); ClassDefinition.AddProperty(Property.FromContentTypeElement("url_slug", "url_slug")); ClassDefinition.AddProperty(Property.FromContentTypeElement("custom", "custom")); @@ -58,9 +59,16 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() var classCodeGenerator = new DeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); var compiledCode = classCodeGenerator.GenerateCode(); + var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); + var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); + var compilation = CSharpCompilation.Create( assemblyName: Path.GetRandomFileName(), - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, + syntaxTrees: new[] + { + CSharpSyntaxTree.ParseText(compiledContentItemCode), + CSharpSyntaxTree.ParseText(compiledCode) + }, references: new[] { MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index 795cbdf2..17eb155a 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -43,8 +43,104 @@ public ExtendedDeliveryClassCodeGeneratorTests() TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("af569649-ee18-4d6a-a095-ea6ffa012546"), "asset", ElementMetadataType.Asset), ElementMetadataType.Asset.ToString())); + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), + ElementMetadataType.RichText + Property.StructuredSuffix)); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a91"), "date_time_structured", ElementMetadataType.DateTime), + ElementMetadataType.DateTime + Property.StructuredSuffix)); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy), + ElementMetadataType.Taxonomy.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug), + ElementMetadataType.UrlSlug.ToString())); + + ClassDefinition.AddProperty(Property.FromContentTypeElement( + TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom), + ElementMetadataType.Custom.ToString())); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Constructor_CreatesInstance(bool generateStructuredModularContent) + { + AddModularContent(generateStructuredModularContent); + + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName, generateStructuredModularContent); + + classCodeGenerator.Should().NotBeNull(); + classCodeGenerator.OverwriteExisting.Should().BeTrue(); + } + + [Theory] + [InlineData("CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels", true)] + [InlineData("CompleteContentType_CompiledCode_ExtendedDeliveryModels", false)] + public void Build_CreatesClassWithCompleteContentType(string fileName, bool generateStructuredModularContent) + { + AddModularContent(generateStructuredModularContent); + + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName, generateStructuredModularContent); + + var compiledCode = classCodeGenerator.GenerateCode(); + + var executingPath = AppContext.BaseDirectory; + var expectedCode = File.ReadAllText($"{executingPath}/Assets/{fileName}.txt"); + + compiledCode.Should().Be(expectedCode); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors(bool generateStructuredModularContent) + { + AddModularContent(generateStructuredModularContent); + + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName, generateStructuredModularContent); + var compiledCode = classCodeGenerator.GenerateCode(); + + var heroClassDefinition = new ClassDefinition("Hero"); + var heroClassCodeGenerator = new ExtendedDeliveryClassCodeGenerator(heroClassDefinition, heroClassDefinition.ClassName, generateStructuredModularContent); + var compiledHeroCode = heroClassCodeGenerator.GenerateCode(); + + var articleClassDefinition = new ClassDefinition("Article"); + var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); + var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); + + var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); + var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); + + var compilation = CSharpCompilation.Create( + assemblyName: Path.GetRandomFileName(), + syntaxTrees: new[] + { + CSharpSyntaxTree.ParseText(compiledContentItemCode), + CSharpSyntaxTree.ParseText(compiledHeroCode), + CSharpSyntaxTree.ParseText(compiledArticleCode), + CSharpSyntaxTree.ParseText(compiledCode), + }, + references: new[] { + MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), + MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq")).Location), + MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) + }, + options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + AssertCompiledCode(compilation); + } + + private void AddModularContent(bool generateStructuredModularContent) + { var singleAllowedTypeMultiItemsTypeName = "Hero"; var singleAllowedTypeExactlySingleItemTypeName = "Article"; + var modularContentType = generateStructuredModularContent + ? ContentItemClassCodeGenerator.DefaultContentItemClassName + : Property.ObjectType; #region LinkedItems @@ -53,14 +149,14 @@ public ExtendedDeliveryClassCodeGeneratorTests() GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "modular_content_heroes", ElementMetadataType.LinkedItems); singleAllowedTypeMultiItems.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{modularContentType}>")); // Linked items element limited to a single type with at most or exactly 1 item. var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, $"IEnumerable<{modularContentType}>")); // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. @@ -71,7 +167,7 @@ public ExtendedDeliveryClassCodeGeneratorTests() Reference.ByCodename("Article") }); multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesSingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesSingleItem, $"IEnumerable<{modularContentType}>")); // Linked items element limited to multiple types with at least 1 item. var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. @@ -82,7 +178,7 @@ public ExtendedDeliveryClassCodeGeneratorTests() Reference.ByCodename("Article") }); multiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesMultiItems, $"IEnumerable<{modularContentType}>")); #endregion @@ -93,14 +189,14 @@ public ExtendedDeliveryClassCodeGeneratorTests() GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee5"), "subpages_heroes", ElementMetadataType.Subpages); subpagesSingleAllowedTypeMultiItems.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeMultiItemsTypeName) }); subpagesSingleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeMultiItems, $"IEnumerable<{modularContentType}>")); // Linked items element limited to a single type with at most or exactly 1 item. var subpagesSingleAllowedTypeExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "subpages_article", ElementMetadataType.Subpages); subpagesSingleAllowedTypeExactlySingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeExactlySingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeExactlySingleItem, $"IEnumerable<{modularContentType}>")); // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. var subpagesMultiAllowedTypesSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. @@ -111,7 +207,7 @@ public ExtendedDeliveryClassCodeGeneratorTests() Reference.ByCodename("Article") }); subpagesMultiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesSingleItem, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesSingleItem, $"IEnumerable<{modularContentType}>")); // Linked items element limited to multiple types with at least 1 item. var subpagesMultiAllowedTypesMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. @@ -122,86 +218,8 @@ public ExtendedDeliveryClassCodeGeneratorTests() Reference.ByCodename("Article") }); subpagesMultiAllowedTypesMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesMultiItems, $"IEnumerable<{ContentItemClassCodeGenerator.DefaultContentItemClassName}>")); + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesMultiItems, $"IEnumerable<{modularContentType}>")); #endregion - - ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("114d2125-923d-4428-93b4-ad1590274912"), "rich_text_structured", ElementMetadataType.RichText), - ElementMetadataType.RichText + Property.StructuredSuffix)); - - ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("66756a72-6af8-44a4-b58c-485425586a91"), "date_time_structured", ElementMetadataType.DateTime), - ElementMetadataType.DateTime + Property.StructuredSuffix)); - - ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("83011da2-559d-458c-a4b5-c81a001f4139"), "taxonomy", ElementMetadataType.Taxonomy), - ElementMetadataType.Taxonomy.ToString())); - - ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("14390f27-213e-4f8d-9c31-cbf9a7c0a0d8"), "url_slug", ElementMetadataType.UrlSlug), - ElementMetadataType.UrlSlug.ToString())); - - ClassDefinition.AddProperty(Property.FromContentTypeElement( - TestDataGenerator.GenerateElementMetadataBase(Guid.Parse("23154ba2-73fc-450c-99d4-c18ba45bb743"), "custom", ElementMetadataType.Custom), - ElementMetadataType.Custom.ToString())); - } - - [Fact] - public void Constructor_CreatesInstance() - { - var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - - classCodeGenerator.Should().NotBeNull(); - classCodeGenerator.OverwriteExisting.Should().BeTrue(); - } - - [Fact] - public void Build_CreatesClassWithCompleteContentType() - { - var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - - var compiledCode = classCodeGenerator.GenerateCode(); - - var executingPath = AppContext.BaseDirectory; - var expectedCode = File.ReadAllText(executingPath + "/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt"); - - compiledCode.Should().Be(expectedCode); - } - - [Fact] - public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() - { - var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); - var compiledCode = classCodeGenerator.GenerateCode(); - - var heroClassDefinition = new ClassDefinition("Hero"); - var heroClassCodeGenerator = new ExtendedDeliveryClassCodeGenerator(heroClassDefinition, heroClassDefinition.ClassName); - var compiledHeroCode = heroClassCodeGenerator.GenerateCode(); - - var articleClassDefinition = new ClassDefinition("Article"); - var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); - var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); - - var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); - var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); - - var compilation = CSharpCompilation.Create( - assemblyName: Path.GetRandomFileName(), - syntaxTrees: new[] - { - CSharpSyntaxTree.ParseText(compiledContentItemCode), - CSharpSyntaxTree.ParseText(compiledHeroCode), - CSharpSyntaxTree.ParseText(compiledArticleCode), - CSharpSyntaxTree.ParseText(compiledCode), - }, - references: new[] { - MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq")).Location), - MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) - }, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - AssertCompiledCode(compilation); } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index 0c27c887..533ad7ed 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -90,10 +90,12 @@ public void Build_CreatesClassWithCompleteContentType() compiledCode.Should().Be(expectedCode); } - [Fact] - public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void IntegrationTest_GeneratedCodeCompilesWithoutErrors(bool generateStructuredModularContent) { - var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); + var classCodeGenerator = new ExtendedDeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName, generateStructuredModularContent); var compiledCode = classCodeGenerator.GenerateCode(); var heroClassDefinition = new ClassDefinition("Hero"); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs index 09ce41a8..aeeb719b 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/DeliveryElementHelperTests.cs @@ -31,7 +31,8 @@ public void GetElementType_ManagementApiIsTrue_ThrowsException() [InlineData(StructuredModelFlags.True, "rich_text", "rich_text(structured)")] [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime, "rich_text", "rich_text(structured)")] [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime, "date_time", "date_time(structured)")] - [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.True | StructuredModelFlags.DateTime, "date_time", "date_time(structured)")] + [InlineData(StructuredModelFlags.ModularContent | StructuredModelFlags.DateTime, "modular_content", "modular_content(structured)")] + [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.True | StructuredModelFlags.DateTime | StructuredModelFlags.ModularContent, "date_time", "date_time(structured)")] public void GetElementType_StructuredModel_ReturnsStructuredElementType(StructuredModelFlags structuredModel, string elementType, string expected) { var result = DeliveryElementHelper.GetElementType(new CodeGeneratorOptions @@ -47,6 +48,7 @@ public void GetElementType_StructuredModel_ReturnsStructuredElementType(Structur [InlineData(StructuredModelFlags.RichText, "date_time", "date_time")] [InlineData(StructuredModelFlags.True, "date_time", "date_time")] [InlineData(StructuredModelFlags.DateTime, "rich_text", "rich_text")] + [InlineData(StructuredModelFlags.ModularContent, "rich_text", "rich_text")] public void GetElementType_StructuredModelForDifferentElement_ReturnsElementType(StructuredModelFlags structuredModel, string elementType, string expected) { var result = DeliveryElementHelper.GetElementType(new CodeGeneratorOptions @@ -62,8 +64,9 @@ public void GetElementType_StructuredModelForDifferentElement_ReturnsElementType [InlineData(StructuredModelFlags.DateTime, "text", "text")] [InlineData(StructuredModelFlags.RichText, "text", "text")] [InlineData(StructuredModelFlags.True, "text", "text")] - [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime, "text", "text")] - [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.True | StructuredModelFlags.DateTime, "text", "text")] + [InlineData(StructuredModelFlags.ModularContent, "text", "text")] + [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.DateTime | StructuredModelFlags.ModularContent, "text", "text")] + [InlineData(StructuredModelFlags.RichText | StructuredModelFlags.True | StructuredModelFlags.DateTime | StructuredModelFlags.ModularContent, "text", "text")] [InlineData(StructuredModelFlags.True | StructuredModelFlags.DateTime, "text", "text")] [InlineData(StructuredModelFlags.NotSet, "text", "text")] public void GetElementType_Returns(StructuredModelFlags structuredModel, string elementType, string expected) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj index bb30d192..611c10fd 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj +++ b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj @@ -16,6 +16,7 @@ + @@ -23,6 +24,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest From 483fdd18d0ae587d9a4d059a31b18e1228976a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 2 Mar 2023 14:01:38 +0100 Subject: [PATCH 34/48] 90 refactoring --- .../Helpers/TypedDeliveryPropertyMapper.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index b3d87113..416de6a4 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -84,10 +84,10 @@ private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List $"{codename}_{typeName}"; - private static Property CreateProperty(ElementMetadataBase element, string propertyName) => Property.FromContentTypeElement( + private static Property CreateProperty(ElementMetadataBase element, string typeName) => Property.FromContentTypeElement( element, - TextHelpers.GetEnumerableType(propertyName), - GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), propertyName)); + TextHelpers.GetEnumerableType(typeName), + GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), typeName)); private static (IEnumerable AllowedTypes, LimitModel ItemCountLimit) GetElementOptions(ElementMetadataBase el) { From 1bae0825e52ed0843f8b60f31dcdbfbab541c672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 2 Mar 2023 14:56:44 +0100 Subject: [PATCH 35/48] 90 fix casing --- .../Helpers/TextHelpers.cs | 51 ++++++++++++------- .../Helpers/TypedDeliveryPropertyMapper.cs | 2 +- .../ExtendedDeliveryCodeGeneratorTests.cs | 8 +-- .../Helpers/TextHelpersTests.cs | 39 +++++++++++++- .../TypedDeliveryPropertyMapperTests.cs | 8 +-- 5 files changed, 80 insertions(+), 28 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs index 29aa563f..6328d220 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TextHelpers.cs @@ -14,24 +14,24 @@ public static class TextHelpers /// /// Returns a valid CSharp Identifier in a Pascal Case format for given string. /// - public static string GetValidPascalCaseIdentifierName(string name) - { - var sanitizedName = Regex.Replace(name, "[^a-zA-Z0-9]", WordSeparator, RegexOptions.IgnoreCase | RegexOptions.Multiline); - - // Remove leading numbers and leading whitespace (e.g.: ' 123Name123' -> 'Name123' - sanitizedName = Regex.Replace(sanitizedName, "^(\\s|[0-9])+", ""); - - if (sanitizedName == string.Empty) - { - throw new InvalidIdentifierException($"Unable to create a valid Identifier from '{name}'"); - } + /// name to be transformed + /// + public static string GetValidPascalCaseIdentifierName(string name) => SplitName(name) + .Select(word => char.ToUpper(word[0]) + word.Substring(1)) + .Aggregate((previous, current) => previous + current); - return sanitizedName - .ToLower() - .Split(new[] { WordSeparator }, StringSplitOptions.RemoveEmptyEntries) - .Select(word => char.ToUpper(word[0]) + word.Substring(1)) - .Aggregate((previous, current) => previous + current); - } + /// + /// Returns a Snake Case format for given string. + /// + /// name to be transformed + /// + public static string GetUpperSnakeCasedIdentifierName(string name) => new string( + SplitName(name) + .Select(word => char.ToUpper(word[0]) + word.Substring(1) + "_") + .Aggregate((previous, current) => previous + current) + .SkipLast(1) + .ToArray() + ); public static string NormalizeLineEndings(this string text) => LineEndings.Replace(text, Environment.NewLine); @@ -55,4 +55,21 @@ public static string GenerateCommentString(string customComment) public static string GetEnumerableType(string typeName) => string.IsNullOrWhiteSpace(typeName) ? throw new ArgumentException("", nameof(typeName)) : $"{nameof(IEnumerable)}<{typeName}>"; + + private static string[] SplitName(string name) + { + var sanitizedName = Regex.Replace(name, "[^a-zA-Z0-9]", WordSeparator, RegexOptions.IgnoreCase | RegexOptions.Multiline); + + // Remove leading numbers and leading whitespace (e.g.: ' 123Name123' -> 'Name123' + sanitizedName = Regex.Replace(sanitizedName, "^(\\s|[0-9])+", ""); + + if (sanitizedName == string.Empty) + { + throw new InvalidIdentifierException($"Unable to create a valid Identifier from '{name}'"); + } + + return sanitizedName + .ToLower() + .Split(new[] { WordSeparator }, StringSplitOptions.RemoveEmptyEntries); + } } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index 416de6a4..45ada684 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -87,7 +87,7 @@ private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List Property.FromContentTypeElement( element, TextHelpers.GetEnumerableType(typeName), - GetCompoundPropertyName(TextHelpers.GetValidPascalCaseIdentifierName(element.Codename), typeName)); + GetCompoundPropertyName(TextHelpers.GetUpperSnakeCasedIdentifierName(element.Codename), typeName)); private static (IEnumerable AllowedTypes, LimitModel ItemCountLimit) GetElementOptions(ElementMetadataBase el) { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index b9883c71..bf0a4f17 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -127,19 +127,19 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(S Property.FromContentTypeElement( LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, $"IEnumerable<{LinkedItemsContentTypeData.HeroContentType.Name}>", - "ModularContentHeroes_Hero"), + "Modular_Content_Heroes_Hero"), Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, LinkedItemsContentTypeData.ArticleContentType.Name), Property.FromContentTypeElement( SubpagesContentTypeData.SingleAllowedTypeMultiItems, $"IEnumerable<{SubpagesContentTypeData.HeroContentType.Name}>", - "SubpagesHeroes_Hero"), + "Subpages_Heroes_Hero"), Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, SubpagesContentTypeData.ArticleContentType.Name) }); expectedTypedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List { - "ModularContentHeroes_Hero", + "Modular_Content_Heroes_Hero", "modular_content_article", - "SubpagesHeroes_Hero", + "Subpages_Heroes_Hero", "subpages_article" }); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs index ca7d9697..609ab1fe 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TextHelpersTests.cs @@ -8,6 +8,41 @@ namespace Kontent.Ai.ModelGenerator.Tests.Helpers; public class TextHelpersTests { + [Fact] + public void GetUpperSnakeCasedIdentifierName_ThrowsAnExceptionForNullValue() + { + var getUpperSnakeCasedIdentifierNameCall = () => TextHelpers.GetUpperSnakeCasedIdentifierName(null); + + getUpperSnakeCasedIdentifierNameCall.Should().ThrowExactly(); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + [InlineData("-")] + [InlineData("$^123")] + public void GetUpperSnakeCasedIdentifierName_ThrowsAnExceptionForInvalidInput(string name) + { + var getUpperSnakeCasedIdentifierNameCall = () => TextHelpers.GetUpperSnakeCasedIdentifierName(name); + + getUpperSnakeCasedIdentifierNameCall.Should().ThrowExactly(); + } + + [Theory] + [InlineData("Simple name", "Simple_Name")] + [InlineData("Name with special chars & multiple spaces.", "Name_With_Special_Chars_Multiple_Spaces")] + [InlineData("EVERYTHING_IS_ -UPPERCASE", "Everything_Is_Uppercase")] + [InlineData("date___time_field", "Date_Time_Field")] + [InlineData("Multiline\r\nstring", "Multiline_String")] + [InlineData(" 1 2 3 Starts with space and numbers", "Starts_With_Space_And_Numbers")] + [InlineData("ends with numbers 1 2 3", "Ends_With_Numbers_1_2_3")] + public void GetUpperSnakeCasedIdentifierName_Returns(string name, string expected) + { + var result = TextHelpers.GetUpperSnakeCasedIdentifierName(name); + + result.Should().Be(expected); + } + [Fact] public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForNullValue() { @@ -36,9 +71,9 @@ public void GetValidPascalCaseIdentifierName_ThrowsAnExceptionForInvalidInput(st [InlineData("Multiline\r\nstring", "MultilineString")] [InlineData(" 1 2 3 Starts with space and numbers", "StartsWithSpaceAndNumbers")] [InlineData("ends with numbers 1 2 3", "EndsWithNumbers123")] - public void GetValidPascalCaseIdentifierName(string name, string expected) + public void GetValidPascalCaseIdentifierName_Returns(string name, string expected) { - string result = TextHelpers.GetValidPascalCaseIdentifierName(name); + var result = TextHelpers.GetValidPascalCaseIdentifierName(name); result.Should().Be(expected); } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 5c16dbfe..174c2726 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -143,9 +143,9 @@ public void TryMap_Live_SingleAllowedTypeMultiItems_Returns(List"); } @@ -287,7 +287,7 @@ public static IEnumerable GetSingleAllowedTypeMultiItems() linkedContentTypeModels, TestDataGenerator.GenerateLinkedItemsElement( Guid.NewGuid().ToString(), - "articles", + "just_articles", limitModel, linkedContentTypeModels.Select(ct => ct.Id)) }; @@ -296,7 +296,7 @@ public static IEnumerable GetSingleAllowedTypeMultiItems() linkedContentTypeModels, TestDataGenerator.GenerateSubpagesElement( Guid.NewGuid().ToString(), - "articles", + "just_articles", limitModel, linkedContentTypeModels.Select(ct => ct.Id)) }; From ba8d418d4567624bb27fbe69271dbfba6db56fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 2 Mar 2023 15:51:30 +0100 Subject: [PATCH 36/48] 90 fix appSettings.json file --- .../appSettings.json | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator/appSettings.json b/src/Kontent.Ai.ModelGenerator/appSettings.json index 2c6d5d7d..dca6107d 100644 --- a/src/Kontent.Ai.ModelGenerator/appSettings.json +++ b/src/Kontent.Ai.ModelGenerator/appSettings.json @@ -7,6 +7,17 @@ "ProjectId": null }, + // Kontent.ai Management SDK Options + "ManagementOptions": { + // Kontent.ai Project ID + "ProjectId": null, + // Kontent.ai Project API key + "ApiKey": null + }, + + // Indicates whether the extended Delivery models should be generated + "ExtendedDeliverModels": false, + // Namespace name of the generated classes "Namespace": null, @@ -23,16 +34,11 @@ "WithTypeProvider": true, // Indicates whether the classes should be generated with types that represent structured data model - "StructuredModel": false, + "StructuredModel": null, //Indicates whether the classes should be generated for Management API SDK "ManagementApi": false, - // Kontent.ai Management SDK Options - "ManagementOptions": { - // Kontent.ai Project ID - "ProjectId": null, - // Kontent.ai Project API key - "ApiKey": null - } + // Indicates whether a base class should be created and all output classes should derive from it using a partial class + "BaseClass": null } From 95bd45c0af179405eb2c3b2bbccada0a3584d125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 3 Mar 2023 11:35:49 +0100 Subject: [PATCH 37/48] 90 docs --- README.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index abd6fbc2..d18a4f41 100644 --- a/README.md +++ b/README.md @@ -47,17 +47,21 @@ To learn how to generate executables for your favorite target platform, follow t ### Delivery API parameters -| Short key | Long key | Required | Default value | Description | -| --------- | :-------------------------------------: | :------: | :---------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID | -| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) | -| `-o` | `--outputdir` | False | `\.` | An output folder path | -| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. | -| `-t` | `--withtypeprovider` | False | `true` | Indicates whether the `CustomTypeProvider` class should be generated (see [Customizing the strong-type binding logic](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/strongly-typed-models.md#customizing-the-strong-type-binding-logic) for more info) | -| `-s` | `--structuredmodel` | False | `null` | Generates `IRichTextContent` instead of `string` for rich-text elements or `IDateTimeContent` instead of `DateTime?` for date-time elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md) [structured date-time rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md). Allowed values [`RichText`, `DateTime`, `True`], as a separator you should use `,`. ⚠️ `True` parameter is **obsolete** and interprets the same value as `RichText`. | -| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | -| `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | -| `-e` | `--extendeddelivermodels` | False | `false` | Indicates whether extended deliver models should be generated | +| Short key | Long key | Required | Default value | Description | +| --------- | :-------------------------------------: | :------: | :---------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID | +| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) | +| `-o` | `--outputdir` | False | `\.` | An output folder path | +| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. | +| `-t` | `--withtypeprovider` | False | `true` | Indicates whether the `CustomTypeProvider` class should be generated (see [Customizing the strong-type binding logic](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/strongly-typed-models.md#customizing-the-strong-type-binding-logic) for more info) | +| `-s` | `--structuredmodel` | False | `null` | For detailed please see [section](https://github.com/kontent-ai/model-generator-net#structured-model) | +| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | +| `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | +| `-e` | `--extendeddelivermodels` | False | `false` | Indicates whether extended deliver models should be generated | + +#### Structured model + +Generates `IRichTextContent` instead of `string` for rich-text elements or `IDateTimeContent` instead of `DateTime?` for date-time elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md) [structured date-time rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md). For *modular content elements* and *subpages* generates `IContentItem` instead of `object`, the model also implements the interface `IContentItem`. Allowed values [`RichText`, `DateTime`, `True`, `ModularContent`], as a separator you should use `,`. ⚠️ `True` parameter is **obsolete** and interprets the same value as `RichText`. ### CLI Syntax @@ -73,7 +77,7 @@ There are two ways of configuring advanced Delivery SDK options (such as secure 1. Command-line arguments `--DeliveryOptions:UseSecureAccess true --DeliveryOptions:SecureAccessApiKey ` ([syntax](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.commandlineconfigurationextensions.addcommandline)) -2. [`appSettings.json`](./src/Kontent.AI.ModelGenerator/appSettings.json) - suitable for the standalone app release +2. [`appSettings.json`](./src/Kontent.Ai.ModelGenerator/appSettings.json) - suitable for the standalone app release ### Delivery API example output @@ -103,7 +107,9 @@ namespace KontentAiModels ``` ### Customizing models - Extended delivery models -Provides support to customize generated models based on content linked/subpages element constraints. This feature uses [Management SDK](https://github.com/kontent-ai/management-sdk-net) thus you'll need to provide api key as well. +Provides support to customize generated models based on content linked/subpages element constraints. This feature uses [Management SDK](https://github.com/kontent-ai/management-sdk-net) thus you'll need to provide api key as well. + +`KontentModelGenerator --projectid "" -e true -k ""` Be aware that the generated models will be implementing the newly generated `IContentItem` interface. ```csharp From ed0a443f23b6834feb8b2b32e9130ee8434f4011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 9 Mar 2023 12:06:10 +0100 Subject: [PATCH 38/48] 90 introduce IContentItem from delivery sdk --- .../Common/Property.cs | 2 +- .../DeliveryCodeGeneratorBase.cs | 3 +- .../ExtendedDeliveryCodeGenerator.cs | 8 +-- .../Class/ContentItemClassCodeGenerator.cs | 38 ------------- .../ExtendedDeliveryClassCodeGenerator.cs | 5 +- .../Kontent.Ai.ModelGenerator.Core.csproj | 6 +-- .../Kontent.Ai.ModelGenerator.csproj | 2 +- .../Assets/IContentItem_CompiledCode.txt | 18 ------- .../ExtendedDeliveryCodeGeneratorTests.cs | 54 ++++++++----------- .../ContentItemClassCodeGeneratorTests.cs | 54 ------------------- .../Class/DeliveryClassCodeGeneratorTests.cs | 4 -- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 7 +-- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 4 -- .../Kontent.Ai.ModelGenerator.Tests.csproj | 8 +-- 14 files changed, 36 insertions(+), 177 deletions(-) delete mode 100644 src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs delete mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt delete mode 100644 test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 1f28f5b3..895115fe 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -42,7 +42,7 @@ public class Property { "multiple_choice", TextHelpers.GetEnumerableType(nameof(IMultipleChoiceOption))}, { "asset", TextHelpers.GetEnumerableType(nameof(IAsset)) }, { ModularContentElementType, TextHelpers.GetEnumerableType(ObjectType) }, - { $"{ModularContentElementType}{StructuredSuffix}", TextHelpers.GetEnumerableType(ContentItemClassCodeGenerator.DefaultContentItemClassName) }, + { $"{ModularContentElementType}{StructuredSuffix}", TextHelpers.GetEnumerableType(nameof(IContentItem)) }, { "taxonomy", TextHelpers.GetEnumerableType(nameof(ITaxonomyTerm)) }, { "url_slug", "string" }, { "custom", "string" } diff --git a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs index 679fc311..80d21b23 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/DeliveryCodeGeneratorBase.cs @@ -40,8 +40,7 @@ private async Task GenerateTypeProvider() foreach (var codeGenerator in classCodeGenerators) { - var className = codeGenerator is ContentItemClassCodeGenerator ? codeGenerator.ClassDefinition.Codename : codeGenerator.ClassDefinition.ClassName; - typeProviderCodeGenerator.AddContentType(codeGenerator.ClassDefinition.Codename, className); + typeProviderCodeGenerator.AddContentType(codeGenerator.ClassDefinition.Codename, codeGenerator.ClassDefinition.ClassName); } var typeProviderCode = typeProviderCodeGenerator.GenerateCode(); diff --git a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs index 9ce30f9a..81ad16d1 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/ExtendedDeliveryCodeGenerator.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management; using Kontent.Ai.Management.Extensions; using Kontent.Ai.Management.Models.Types; @@ -45,11 +46,6 @@ protected override async Task> GetClassCodeGener return codeGenerators; } - if (Options.IsStructuredModelModularContent()) - { - codeGenerators.Add(new ContentItemClassCodeGenerator(Options.Namespace)); - } - foreach (var contentType in deliveryTypes) { try @@ -116,7 +112,7 @@ private void AddProperty(ElementMetadataBase el, ref ClassDefinition classDefini } var linkedObjectType = Options.IsStructuredModelModularContent() - ? ContentItemClassCodeGenerator.DefaultContentItemClassName + ? nameof(IContentItem) : Property.ObjectType; elementType = TextHelpers.GetEnumerableType(linkedObjectType); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs deleted file mode 100644 index 0565131b..00000000 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ContentItemClassCodeGenerator.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Kontent.Ai.ModelGenerator.Core.Common; -using Kontent.Ai.ModelGenerator.Core.Helpers; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace Kontent.Ai.ModelGenerator.Core.Generators.Class; - -public class ContentItemClassCodeGenerator : ClassCodeGenerator -{ - public const string DefaultContentItemClassName = "IContentItem"; - - public ContentItemClassCodeGenerator(string @namespace = DefaultNamespace) - : base(new ClassDefinition(DefaultContentItemClassName), DefaultContentItemClassName, @namespace) - { - } - - protected override UsingDirectiveSyntax[] GetApiUsings() => new UsingDirectiveSyntax[] - { - SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(typeof(Delivery.Abstractions.IApiResponse).Namespace!)) - }; - - protected override TypeDeclarationSyntax GetClassDeclaration() - { - ClassDefinition.TryAddSystemProperty(); - - var classDeclaration = SyntaxFactory.InterfaceDeclaration(ClassDefinition.Codename) - .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) - .AddMembers(Properties); - - return classDeclaration; - } - - protected override SyntaxTrivia ClassDescription() => ClassDeclarationHelper.GenerateSyntaxTrivia( - @$"{LostChangesComment} -// Class is meant to represent common IContentItem interface, thus is not suitable for further modifications. -// If you require to extend all of your generated models you can use base classes see https://bit.ly/3yugE2z."); -} diff --git a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs index 04ff9171..069037dd 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Generators/Class/ExtendedDeliveryClassCodeGenerator.cs @@ -1,4 +1,5 @@ -using Kontent.Ai.ModelGenerator.Core.Common; +using Kontent.Ai.Delivery.Abstractions; +using Kontent.Ai.ModelGenerator.Core.Common; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -22,7 +23,7 @@ protected override TypeDeclarationSyntax GetClassDeclaration() if (_generateStructuredModularContent) { - var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(ContentItemClassCodeGenerator.DefaultContentItemClassName)); + var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(nameof(IContentItem))); classDeclaration = (TypeDeclarationSyntax)classDeclaration.AddBaseListTypes(baseType); } diff --git a/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj b/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj index 75f89e8a..08ea07f1 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj +++ b/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj @@ -25,15 +25,15 @@ - + - - + + diff --git a/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj b/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj index b54fd308..7e8a63a8 100644 --- a/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj +++ b/src/Kontent.Ai.ModelGenerator/Kontent.Ai.ModelGenerator.csproj @@ -36,7 +36,7 @@ - + diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt deleted file mode 100644 index 62b288b3..00000000 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/IContentItem_CompiledCode.txt +++ /dev/null @@ -1,18 +0,0 @@ -// -// This code was generated by a kontent-generators-net tool -// (see https://github.com/kontent-ai/model-generator-net). -// -// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. -// Class is meant to represent common IContentItem interface, thus is not suitable for further modifications. -// If you require to extend all of your generated models you can use base classes see https://bit.ly/3yugE2z. -// - -using Kontent.Ai.Delivery.Abstractions; - -namespace KontentAiModels -{ - public interface IContentItem - { - public IContentItemSystemAttributes System { get; set; } - } -} \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index bf0a4f17..33226737 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using FluentAssertions; +using Kontent.Ai.Delivery.Abstractions; using Kontent.Ai.Management; using Kontent.Ai.Management.Configuration; using Kontent.Ai.Management.Models.Types; @@ -26,7 +27,7 @@ public class ExtendedDeliveryCodeGeneratorTests : CodeGeneratorTestsBase /// /// represents count of elements in 'management_types.json' /// - private const int NumberOfContentTypesWithDefaultContentItem = (14 * 2) + 1; + private const int NumberOfContentTypesWithDefaultContentItem = (14 * 2); private readonly IManagementClient _managementClient; private readonly IOutputProvider _outputProvider; @@ -177,9 +178,9 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(S } [Theory] - [InlineData(StructuredModelFlags.ModularContent, NumberOfContentTypesWithDefaultContentItem)] - [InlineData(StructuredModelFlags.NotSet, NumberOfContentTypesWithDefaultContentItem - 1)] - public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags structuredModel, int expectedNumberOfFiles) + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags structuredModel) { var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions @@ -198,9 +199,7 @@ public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags str await codeGenerator.RunAsync(); - AssertPresenceOfIContentItemFile(structuredModel); - - Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(expectedNumberOfFiles); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem); Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*.Generated.cs").Should().NotBeEmpty(); Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(p => !p.Contains("*.Generated.cs")).Should().NotBeEmpty(); @@ -210,9 +209,9 @@ public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags str } [Theory] - [InlineData(StructuredModelFlags.ModularContent, NumberOfContentTypesWithDefaultContentItem)] - [InlineData(StructuredModelFlags.NotSet, NumberOfContentTypesWithDefaultContentItem - 1)] - public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(StructuredModelFlags structuredModel, int expectedNumberOfFiles) + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(StructuredModelFlags structuredModel) { const string transformFilename = "CustomSuffix"; var mockOptions = new Mock>(); @@ -233,11 +232,9 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(Structur await codeGenerator.RunAsync(); - AssertPresenceOfIContentItemFile(structuredModel); - - Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(expectedNumberOfFiles); + Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(NumberOfContentTypesWithDefaultContentItem); - foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir)).Where(f => !f.Contains($"{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs"))) + foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir))) { Path.GetFileName(filepath).Should().EndWith($".{transformFilename}.cs"); } @@ -247,9 +244,9 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(Structur } [Theory] - [InlineData(StructuredModelFlags.ModularContent, 1)] - [InlineData(StructuredModelFlags.NotSet, 0)] - public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(StructuredModelFlags structuredModel, int numberOfExtraGeneratedFiles) + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(StructuredModelFlags structuredModel) { const string transformFilename = "Generated"; var mockOptions = new Mock>(); @@ -272,15 +269,12 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(Structu var allFilesCount = Directory.GetFiles(Path.GetFullPath(TempDir), "*.cs").Length; var generatedCount = Directory.GetFiles(Path.GetFullPath(TempDir), $"*.{transformFilename}.cs").Length; - var result = generatedCount + (generatedCount / 2) + numberOfExtraGeneratedFiles; + var result = generatedCount + (generatedCount / 2); result.Should().Be(allFilesCount); - AssertPresenceOfIContentItemFile(structuredModel); - foreach (var filepath in Directory.EnumerateFiles(Path.GetFullPath(TempDir)) .Where(f => - !f.Contains($"{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs") && !f.Contains($".{transformFilename}.cs") && !f.Contains($"{ExtendedDeliveryCodeGenerator.TypedSuffixFileName}.{transformFilename}.cs"))) { @@ -296,9 +290,9 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(Structu } [Theory] - [InlineData(StructuredModelFlags.ModularContent, NumberOfContentTypesWithDefaultContentItem + 1)] - [InlineData(StructuredModelFlags.NotSet, NumberOfContentTypesWithDefaultContentItem)] - public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(StructuredModelFlags structuredModel, int expectedNumberOfFiles) + [InlineData(StructuredModelFlags.ModularContent)] + [InlineData(StructuredModelFlags.NotSet)] + public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(StructuredModelFlags structuredModel) { var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions @@ -317,9 +311,9 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(StructuredM await codeGenerator.RunAsync(); - AssertPresenceOfIContentItemFile(structuredModel); + var generatedFilesWithoutTypeProvider = Directory.GetFiles(Path.GetFullPath(TempDir)).Where(f => !f.EndsWith("TypeProvider.cs")).ToList(); - Directory.GetFiles(Path.GetFullPath(TempDir)).Length.Should().Be(expectedNumberOfFiles); + generatedFilesWithoutTypeProvider.Count.Should().Be(NumberOfContentTypesWithDefaultContentItem); Directory.EnumerateFiles(Path.GetFullPath(TempDir), "*TypeProvider.cs").Should().NotBeEmpty(); @@ -333,13 +327,7 @@ private Func Creator(IOptions TextHelpers.GetEnumerableType( structuredModel.HasFlag(StructuredModelFlags.ModularContent) - ? ContentItemClassCodeGenerator.DefaultContentItemClassName + ? nameof(IContentItem) : Property.ObjectType ); - - private void AssertPresenceOfIContentItemFile(StructuredModelFlags structuredModel) - { - var defaultContentItemClassCodeGeneratorExists = File.Exists(Path.GetFullPath($"{TempDir}//{ContentItemClassCodeGenerator.DefaultContentItemClassName}.cs")); - defaultContentItemClassCodeGeneratorExists.Should().Be(structuredModel is StructuredModelFlags.ModularContent); - } } \ No newline at end of file diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs deleted file mode 100644 index df6d6437..00000000 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ContentItemClassCodeGeneratorTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Kontent.Ai.ModelGenerator.Core.Generators.Class; -using System; -using System.IO; -using System.Reflection; -using FluentAssertions; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Xunit; - -namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; - -public class ContentItemClassCodeGeneratorTests : ClassCodeGeneratorTestsBase -{ - [Fact] - public void Constructor_CreatesInstance() - { - var classCodeGenerator = new ContentItemClassCodeGenerator(); - - classCodeGenerator.Should().NotBeNull(); - classCodeGenerator.OverwriteExisting.Should().BeTrue(); - } - - [Fact] - public void Build_CreatesClassWithSystemProperty() - { - var classCodeGenerator = new ContentItemClassCodeGenerator(); - - var compiledCode = classCodeGenerator.GenerateCode(); - - var executingPath = AppContext.BaseDirectory; - var expectedCode = File.ReadAllText(executingPath + "/Assets/IContentItem_CompiledCode.txt"); - - compiledCode.Should().Be(expectedCode); - } - - [Fact] - public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() - { - var classCodeGenerator = new ContentItemClassCodeGenerator(); - - var compiledCode = classCodeGenerator.GenerateCode(); - - var compilation = CSharpCompilation.Create( - assemblyName: Path.GetRandomFileName(), - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledCode) }, - references: new[] { - MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location), - MetadataReference.CreateFromFile(typeof(Delivery.Abstractions.IApiResponse).GetTypeInfo().Assembly.Location) - }, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - AssertCompiledCode(compilation); - } -} diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs index 04863b4a..fe497216 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/DeliveryClassCodeGeneratorTests.cs @@ -59,14 +59,10 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors() var classCodeGenerator = new DeliveryClassCodeGenerator(ClassDefinition, ClassDefinition.ClassName); var compiledCode = classCodeGenerator.GenerateCode(); - var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); - var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); - var compilation = CSharpCompilation.Create( assemblyName: Path.GetRandomFileName(), syntaxTrees: new[] { - CSharpSyntaxTree.ParseText(compiledContentItemCode), CSharpSyntaxTree.ParseText(compiledCode) }, references: new[] { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index 17eb155a..1a5bf21b 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -12,6 +12,7 @@ using Kontent.Ai.Management.Models.Types; using Kontent.Ai.ModelGenerator.Tests.TestHelpers; using FluentAssertions; +using Kontent.Ai.Delivery.Abstractions; namespace Kontent.Ai.ModelGenerator.Tests.Generators.Class; @@ -112,14 +113,10 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors(bool generateStru var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); - var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); - var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); - var compilation = CSharpCompilation.Create( assemblyName: Path.GetRandomFileName(), syntaxTrees: new[] { - CSharpSyntaxTree.ParseText(compiledContentItemCode), CSharpSyntaxTree.ParseText(compiledHeroCode), CSharpSyntaxTree.ParseText(compiledArticleCode), CSharpSyntaxTree.ParseText(compiledCode), @@ -139,7 +136,7 @@ private void AddModularContent(bool generateStructuredModularContent) var singleAllowedTypeMultiItemsTypeName = "Hero"; var singleAllowedTypeExactlySingleItemTypeName = "Article"; var modularContentType = generateStructuredModularContent - ? ContentItemClassCodeGenerator.DefaultContentItemClassName + ? nameof(IContentItem) : Property.ObjectType; #region LinkedItems diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index 533ad7ed..870576ba 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -106,14 +106,10 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors(bool generateStru var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); - var contentItemCodeGenerator = new ContentItemClassCodeGenerator(); - var compiledContentItemCode = contentItemCodeGenerator.GenerateCode(); - var compilation = CSharpCompilation.Create( assemblyName: Path.GetRandomFileName(), syntaxTrees: new[] { - CSharpSyntaxTree.ParseText(compiledContentItemCode), CSharpSyntaxTree.ParseText(compiledHeroCode), CSharpSyntaxTree.ParseText(compiledArticleCode), CSharpSyntaxTree.ParseText(compiledCode), diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj index 611c10fd..def202d1 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj +++ b/test/Kontent.Ai.ModelGenerator.Tests/Kontent.Ai.ModelGenerator.Tests.csproj @@ -17,7 +17,6 @@ - @@ -30,9 +29,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -63,8 +59,8 @@ - - + + From c9aae6d1271d9eeaa87cd8f0a33a5716e349faba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 9 Mar 2023 12:36:04 +0100 Subject: [PATCH 39/48] 90 docs --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d18a4f41..729ffdd7 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ To learn how to generate executables for your favorite target platform, follow t #### Structured model -Generates `IRichTextContent` instead of `string` for rich-text elements or `IDateTimeContent` instead of `DateTime?` for date-time elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md) [structured date-time rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md). For *modular content elements* and *subpages* generates `IContentItem` instead of `object`, the model also implements the interface `IContentItem`. Allowed values [`RichText`, `DateTime`, `True`, `ModularContent`], as a separator you should use `,`. ⚠️ `True` parameter is **obsolete** and interprets the same value as `RichText`. +Generates `IRichTextContent` instead of `string` for rich-text elements or `IDateTimeContent` instead of `DateTime?` for date-time elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md) [structured date-time rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md). For *modular content elements* and *subpages* generates [`IContentItem`](https://github.com/kontent-ai/delivery-sdk-net/blob/master/Kontent.Ai.Delivery.Abstractions/ContentItems/IContentItem.cs) instead of `object`, the model also implements the interface `IContentItem`. Allowed values [`RichText`, `DateTime`, `True`, `ModularContent`], as a separator you should use `,`. ⚠️ `True` parameter is **obsolete** and interprets the same value as `RichText`. ### CLI Syntax @@ -111,15 +111,8 @@ Provides support to customize generated models based on content linked/subpages `KontentModelGenerator --projectid "" -e true -k ""` -Be aware that the generated models will be implementing the newly generated `IContentItem` interface. -```csharp -public interface IContentItem -{ - public IContentItemSystemAttributes System { get; set; } -} -``` - #### Extended delivery models example output +Model is generated using structured model option ModularContent. Model.Generated.cs ```csharp From 41af3bf0fb3878a91d9beb8f0327e59804af4248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Wed, 15 Mar 2023 20:53:07 +0100 Subject: [PATCH 40/48] 90 review fixes --- .../Configuration/CodeGeneratorOptionsExtensionsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index 4baa523e..ebedc0e8 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -173,7 +173,7 @@ public void ManagementApi_InvalidConfig_ReturnsFalse(bool managementApi) { var options = new CodeGeneratorOptions { - ManagementApi = true, + ManagementApi = managementApi, ExtendedDeliverModels = true }; From 0c451331712709552b8890a6c529c914d2741d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 16 Mar 2023 13:18:22 +0100 Subject: [PATCH 41/48] 90 introduce SingleAllowedTypeAtMostSingleItem --- README.md | 6 ++ .../Helpers/TypedDeliveryPropertyMapper.cs | 3 +- ...pe_CompiledCode_ExtendedDeliveryModels.txt | 4 ++ ...dModularContent_ExtendedDeliveryModels.txt | 4 ++ ...mpiledCode_TypedExtendedDeliveryModels.txt | 4 ++ .../ExtendedDeliveryCodeGeneratorTests.cs | 28 ++++++-- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 62 ++++++++++++++---- ...ExtendedDeliveryClassCodeGeneratorTests.cs | 24 ++++++- .../TypedDeliveryPropertyMapperTests.cs | 64 +++++++++++++++++++ .../TestHelpers/LinkedItemsContentTypeData.cs | 42 ++++++++++-- .../TestHelpers/SubpagesContentTypeData.cs | 42 ++++++++++-- 11 files changed, 253 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 729ffdd7..9f16fc95 100644 --- a/README.md +++ b/README.md @@ -118,11 +118,15 @@ Model.Generated.cs ```csharp public partial class Home : IContentItem { + public const string SingleAllowedTypeAtMostOneLinkedContentItemCodename = "single_allowed_type_at_most_one_linked_content_item"; public const string SingleAllowedTypeSingleLinkedContentItemCodename = "single_allowed_type_single_linked_content_item"; public const string SingleAllowedTypeMultiLinkedContentItemsCodename = "single_allowed_type_multi_linked_content_items"; public const string MultiAllowedTypesSingleLinkedContentItemCodename = "multi_allowed_types_single_linked_content_item"; public const string MultiAllowedTypesMultiLinkedContentItemsCodename = "multi_allowed_types_multi_linked_content_items"; + // Allowed Content Types == "Article" && Limit number of items <= 1 + public IEnumerable SingleAllowedTypeAtMostOneLinkedContentItem { get; set; } + // Allowed Content Types == "Article" && Limit number of items == 1 public IEnumerable SingleAllowedTypeSingleLinkedContentItem { get; set; } @@ -142,6 +146,8 @@ Model.Typed.Generated.cs ```csharp public partial class Home { + public Article SingleAllowedTypeAtMostOneLinkedContentItemSingle => SingleAllowedTypeAtMostOneLinkedContentItem.OfType
().FirstOrDefault(); + public Article SingleAllowedTypeSingleLinkedContentItemSingle => SingleAllowedTypeSingleLinkedContentItem.OfType
().FirstOrDefault(); public IEnumerable
SingleAllowedTypeMultiLinkedContentItemsArticleTyped => SingleAllowedTypeMultiLinkedContentItems.OfType
(); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index 45ada684..042b34c3 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -32,7 +32,8 @@ public static bool TryMap( var allowedContentType = GetAllowedContentType(elementOptions.AllowedTypes.First().Id.Value, contentTypes); var allowedContentTypeCodename = TextHelpers.GetValidPascalCaseIdentifierName(allowedContentType.Codename); - if (elementOptions.ItemCountLimit is { Condition: LimitType.Exactly, Value: 1 }) + if (elementOptions.ItemCountLimit.Value == 1 && + (elementOptions.ItemCountLimit.Condition is LimitType.Exactly or LimitType.AtMost)) { typedProperty = Property.FromContentTypeElement(el, allowedContentTypeCodename); return true; diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt index 067ceabb..a22082a8 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_ExtendedDeliveryModels.txt @@ -22,7 +22,9 @@ namespace KontentAiModels public IDateTimeContent DateTimeStructured { get; set; } public IEnumerable ModularContentArticle { get; set; } public IEnumerable ModularContentBlog { get; set; } + public IEnumerable ModularContentCoffee { get; set; } public IEnumerable ModularContentCoffees { get; set; } + public IEnumerable ModularContentHero { get; set; } public IEnumerable ModularContentHeroes { get; set; } public IEnumerable MultipleChoice { get; set; } public decimal? Number { get; set; } @@ -30,7 +32,9 @@ namespace KontentAiModels public IRichTextContent RichTextStructured { get; set; } public IEnumerable SubpagesArticle { get; set; } public IEnumerable SubpagesBlog { get; set; } + public IEnumerable SubpagesCoffee { get; set; } public IEnumerable SubpagesCoffees { get; set; } + public IEnumerable SubpagesHero { get; set; } public IEnumerable SubpagesHeroes { get; set; } public IContentItemSystemAttributes System { get; set; } public IEnumerable Taxonomy { get; set; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt index 37b9441d..0a210b4d 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_StructuredModularContent_ExtendedDeliveryModels.txt @@ -22,7 +22,9 @@ namespace KontentAiModels public IDateTimeContent DateTimeStructured { get; set; } public IEnumerable ModularContentArticle { get; set; } public IEnumerable ModularContentBlog { get; set; } + public IEnumerable ModularContentCoffee { get; set; } public IEnumerable ModularContentCoffees { get; set; } + public IEnumerable ModularContentHero { get; set; } public IEnumerable ModularContentHeroes { get; set; } public IEnumerable MultipleChoice { get; set; } public decimal? Number { get; set; } @@ -30,7 +32,9 @@ namespace KontentAiModels public IRichTextContent RichTextStructured { get; set; } public IEnumerable SubpagesArticle { get; set; } public IEnumerable SubpagesBlog { get; set; } + public IEnumerable SubpagesCoffee { get; set; } public IEnumerable SubpagesCoffees { get; set; } + public IEnumerable SubpagesHero { get; set; } public IEnumerable SubpagesHeroes { get; set; } public IContentItemSystemAttributes System { get; set; } public IEnumerable Taxonomy { get; set; } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt index 97ec8b39..03453b76 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt +++ b/test/Kontent.Ai.ModelGenerator.Tests/Assets/CompleteContentType_CompiledCode_TypedExtendedDeliveryModels.txt @@ -17,8 +17,12 @@ namespace KontentAiModels { public Article ModularContentArticleSingle => ModularContentArticle.OfType
().FirstOrDefault(); + public Nemesis ModularContentNemesisSingle => ModularContentNemesis.OfType().FirstOrDefault(); + public Article SubpagesArticleSingle => SubpagesArticle.OfType
().FirstOrDefault(); + public Nemesis SubpagesNemesisSingle => SubpagesNemesis.OfType().FirstOrDefault(); + public IEnumerable ModularContentHeroesHeroTyped => ModularContentHeroes.OfType(); public IEnumerable SubpagesHeroesHeroTyped => SubpagesHeroes.OfType(); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index 33226737..5c8c747c 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -100,11 +100,15 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(S { LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, - LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, + LinkedItemsContentTypeData.SingleAllowedTypeAtMostSingleItem, + LinkedItemsContentTypeData.MultiAllowedTypesExactlySingleItem, + LinkedItemsContentTypeData.MultiAllowedTypesAtMostSingleItem, LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, SubpagesContentTypeData.SingleAllowedTypeMultiItems, SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, - SubpagesContentTypeData.MultiAllowedTypesSingleItem, + SubpagesContentTypeData.SingleAllowedTypeAtMostSingleItem, + SubpagesContentTypeData.MultiAllowedTypesExactlySingleItem, + SubpagesContentTypeData.MultiAllowedTypesAtMostSingleItem, SubpagesContentTypeData.MultiAllowedTypesMultiItems, } }; @@ -130,18 +134,22 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(S $"IEnumerable<{LinkedItemsContentTypeData.HeroContentType.Name}>", "Modular_Content_Heroes_Hero"), Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, LinkedItemsContentTypeData.ArticleContentType.Name), + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeAtMostSingleItem, LinkedItemsContentTypeData.HeroContentType.Name), Property.FromContentTypeElement( SubpagesContentTypeData.SingleAllowedTypeMultiItems, $"IEnumerable<{SubpagesContentTypeData.HeroContentType.Name}>", "Subpages_Heroes_Hero"), - Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, SubpagesContentTypeData.ArticleContentType.Name) + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, SubpagesContentTypeData.ArticleContentType.Name), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeAtMostSingleItem, SubpagesContentTypeData.HeroContentType.Name) }); expectedTypedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List { "Modular_Content_Heroes_Hero", "modular_content_article", + "modular_content_hero", "Subpages_Heroes_Hero", - "subpages_article" + "subpages_article", + "subpages_hero" }); var expectedExtendedDeliveryClassDefinition = new ClassDefinition(contentType.Codename); @@ -149,22 +157,30 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(S { Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType(structuredModel)), Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType(structuredModel)), - Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(LinkedItemsContentTypeData.SingleAllowedTypeAtMostSingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesExactlySingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesAtMostSingleItem, DefaultLinkedItemsType(structuredModel)), Property.FromContentTypeElement(LinkedItemsContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType(structuredModel)), Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeMultiItems, DefaultLinkedItemsType(structuredModel)), Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeExactlySingleItem, DefaultLinkedItemsType(structuredModel)), - Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesSingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.SingleAllowedTypeAtMostSingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesExactlySingleItem, DefaultLinkedItemsType(structuredModel)), + Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesAtMostSingleItem, DefaultLinkedItemsType(structuredModel)), Property.FromContentTypeElement(SubpagesContentTypeData.MultiAllowedTypesMultiItems, DefaultLinkedItemsType(structuredModel)) }); expectedExtendedDeliveryClassDefinition.PropertyCodenameConstants.AddRange(new List { "modular_content_heroes", "modular_content_article", + "modular_content_hero", "modular_content_blog", + "modular_content_coffee", "modular_content_coffees", "subpages_heroes", "subpages_article", + "subpages_hero", "subpages_blog", + "subpages_coffee", "subpages_coffees" }); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs index 1a5bf21b..02970f23 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/ExtendedDeliveryClassCodeGeneratorTests.cs @@ -148,23 +148,41 @@ private void AddModularContent(bool generateStructuredModularContent) singleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeMultiItems, $"IEnumerable<{modularContentType}>")); - // Linked items element limited to a single type with at most or exactly 1 item. + // Linked items element limited to a single type with exactly 1 item. var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, $"IEnumerable<{modularContentType}>")); - // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. - var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + // Linked items element limited to a single type with at most 1 item. + var singleAllowedTypeAtMostSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "modular_content_hero", ElementMetadataType.LinkedItems); + singleAllowedTypeAtMostSingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); + singleAllowedTypeAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeAtMostSingleItem, $"IEnumerable<{modularContentType}>")); + + // Linked items element limited to multiple types with exactly 1 item. + var multiAllowedTypesExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "modular_content_blog", ElementMetadataType.LinkedItems); - multiAllowedTypesSingleItem.AllowedTypes = new List(new List + multiAllowedTypesExactlySingleItem.AllowedTypes = new List(new List + { + Reference.ByCodename("Hero"), + Reference.ByCodename("Article") + }); + multiAllowedTypesExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesExactlySingleItem, $"IEnumerable<{modularContentType}>")); + + // Linked items element limited to multiple types with at most 1 item. + var multiAllowedTypesAtMostSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ccc"), "modular_content_coffee", ElementMetadataType.LinkedItems); + multiAllowedTypesAtMostSingleItem.AllowedTypes = new List(new List { Reference.ByCodename("Hero"), Reference.ByCodename("Article") }); - multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesSingleItem, $"IEnumerable<{modularContentType}>")); + multiAllowedTypesAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(multiAllowedTypesAtMostSingleItem, $"IEnumerable<{modularContentType}>")); // Linked items element limited to multiple types with at least 1 item. var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. @@ -188,23 +206,41 @@ private void AddModularContent(bool generateStructuredModularContent) subpagesSingleAllowedTypeMultiItems.ItemCountLimit = new LimitModel { Condition = LimitType.AtLeast, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeMultiItems, $"IEnumerable<{modularContentType}>")); - // Linked items element limited to a single type with at most or exactly 1 item. + // Linked items element limited to a single type with exactly 1 item. var subpagesSingleAllowedTypeExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "subpages_article", ElementMetadataType.Subpages); subpagesSingleAllowedTypeExactlySingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); - singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + subpagesSingleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeExactlySingleItem, $"IEnumerable<{modularContentType}>")); - // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. - var subpagesMultiAllowedTypesSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + // Linked items element limited to a single type with at most 1 item. + var subpagesSingleAllowedTypeAtMostSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee8"), "subpages_hero", ElementMetadataType.Subpages); + subpagesSingleAllowedTypeAtMostSingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); + subpagesSingleAllowedTypeAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeAtMostSingleItem, $"IEnumerable<{modularContentType}>")); + + // Linked items element limited to multiple types with exactly 1 item. + var subpagesMultiAllowedTypesExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "subpages_blog", ElementMetadataType.Subpages); - subpagesMultiAllowedTypesSingleItem.AllowedContentTypes = new List(new List + subpagesMultiAllowedTypesExactlySingleItem.AllowedContentTypes = new List(new List + { + Reference.ByCodename("Hero"), + Reference.ByCodename("Article") + }); + subpagesMultiAllowedTypesExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesExactlySingleItem, $"IEnumerable<{modularContentType}>")); + + // Linked items element limited to multiple types with at least 1 at most or exactly 1 item. + var subpagesMultiAllowedTypesAtMostSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "subpages_coffee", ElementMetadataType.Subpages); + subpagesMultiAllowedTypesAtMostSingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename("Hero"), Reference.ByCodename("Article") }); - subpagesMultiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; - ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesSingleItem, $"IEnumerable<{modularContentType}>")); + subpagesMultiAllowedTypesAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesMultiAllowedTypesAtMostSingleItem, $"IEnumerable<{modularContentType}>")); // Linked items element limited to multiple types with at least 1 item. var subpagesMultiAllowedTypesMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs index 870576ba..1b784d5b 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Generators/Class/TypedExtendedDeliveryClassCodeGeneratorTests.cs @@ -22,6 +22,7 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() { var singleAllowedTypeMultiItemsTypeName = "Hero"; var singleAllowedTypeExactlySingleItemTypeName = "Article"; + var singleAllowedTypeAtMostSingleItemTypeName = "Nemesis"; #region LinkedItems @@ -36,13 +37,20 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() TextHelpers.GetEnumerableType(singleAllowedTypeMultiItemsTypeName), $"{singleAllowedTypeMultiItemsTypeCodename}_{singleAllowedTypeMultiItemsTypeName}")); - // Linked items element limited to a single type with at most or exactly 1 item. + // Linked items element limited to a single type with exactly 1 item. var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.NewGuid(), "modular_content_article", ElementMetadataType.LinkedItems); singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeExactlySingleItem, singleAllowedTypeExactlySingleItemTypeName)); + // Linked items element limited to a single type with at most 1 item. + var singleAllowedTypeAtMostSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.NewGuid(), "modular_content_nemesis", ElementMetadataType.LinkedItems); + singleAllowedTypeAtMostSingleItem.AllowedTypes = new List(new List { Reference.ByCodename(singleAllowedTypeAtMostSingleItemTypeName) }); + singleAllowedTypeAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(singleAllowedTypeAtMostSingleItem, singleAllowedTypeAtMostSingleItemTypeName)); + #endregion #region Subpages @@ -58,13 +66,20 @@ public TypedExtendedDeliveryClassCodeGeneratorTests() TextHelpers.GetEnumerableType(singleAllowedTypeMultiItemsTypeName), $"{subpagesSingleAllowedTypeMultiItemsTypeCodename}_{singleAllowedTypeMultiItemsTypeName}")); - // Subpages element limited to a single type with at most or exactly 1 item. + // Subpages element limited to a single type with exactly 1 item. var subpagesSingleAllowedTypeExactlySingleItem = (SubpagesElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.NewGuid(), "subpages_article", ElementMetadataType.Subpages); subpagesSingleAllowedTypeExactlySingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeExactlySingleItemTypeName) }); subpagesSingleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeExactlySingleItem, singleAllowedTypeExactlySingleItemTypeName)); + // Subpages element limited to a single type with at most 1 item. + var subpagesSingleAllowedTypeAtMostSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.NewGuid(), "subpages_nemesis", ElementMetadataType.Subpages); + subpagesSingleAllowedTypeAtMostSingleItem.AllowedContentTypes = new List(new List { Reference.ByCodename(singleAllowedTypeAtMostSingleItemTypeName) }); + subpagesSingleAllowedTypeAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + ClassDefinition.AddProperty(Property.FromContentTypeElement(subpagesSingleAllowedTypeAtMostSingleItem, singleAllowedTypeAtMostSingleItemTypeName)); + #endregion } @@ -106,12 +121,17 @@ public void IntegrationTest_GeneratedCodeCompilesWithoutErrors(bool generateStru var articleClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(articleClassDefinition, articleClassDefinition.ClassName); var compiledArticleCode = articleClassCodeGenerator.GenerateCode(); + var nemesisClassDefinition = new ClassDefinition("Nemesis"); + var nemesisClassCodeGenerator = new TypedExtendedDeliveryClassCodeGenerator(nemesisClassDefinition, nemesisClassDefinition.ClassName); + var compiledNemesisCode = nemesisClassCodeGenerator.GenerateCode(); + var compilation = CSharpCompilation.Create( assemblyName: Path.GetRandomFileName(), syntaxTrees: new[] { CSharpSyntaxTree.ParseText(compiledHeroCode), CSharpSyntaxTree.ParseText(compiledArticleCode), + CSharpSyntaxTree.ParseText(compiledNemesisCode), CSharpSyntaxTree.ParseText(compiledCode), }, references: new[] { diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index 174c2726..d9e8e391 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -176,6 +176,33 @@ public void TryMap_Live_SingleAllowedTypeExactlySingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) + { + var allContentTypes = new List() + { + new ContentTypeModel + { + Codename = "grinder", + Id = Guid.NewGuid() + }, + new ContentTypeModel + { + Codename = "coffee", + Id = Guid.NewGuid() + } + }.Union(linkedContentTypeModels).ToList(); + + var result = TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out var typedProperty); + + result.Should().BeTrue(); + typedProperty.Codename.Should().Be("article"); + typedProperty.Id.Should().BeNull(); + typedProperty.Identifier.Should().Be("Article"); + typedProperty.TypeName.Should().Be("Article"); + } + [Theory] [MemberData(nameof(GetMultiAllowedTypesSingleItem))] public void TryMap_Live_MultiAllowedTypesSingleItem_Returns(List linkedContentTypeModels, ElementMetadataBase element) @@ -339,6 +366,43 @@ public static IEnumerable GetSingleAllowedTypeExactlySingleItem() }; } + public static IEnumerable GetSingleAllowedTypeAtMostSingleItem() + { + var limitModel = new LimitModel + { + Condition = LimitType.AtMost, + Value = 1 + }; + + var linkedContentTypeModels = new List() + { + new ContentTypeModel + { + Codename = "article", + Id = Guid.NewGuid() + } + }; + + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateLinkedItemsElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "article", + limitModel, + linkedContentTypeModels.Select(ct => ct.Id)) + }; + } + public static IEnumerable GetMultiAllowedTypesSingleItem() { var limitModel = new LimitModel diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs index bd4ffbe1..5fb17243 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/LinkedItemsContentTypeData.cs @@ -28,14 +28,24 @@ public static class LinkedItemsContentTypeData public static LinkedItemsElementMetadataModel SingleAllowedTypeMultiItems = GenerateSingleAllowedTypeMultiItems(); /// - /// Represents linked items element limited to a single type with at most or exactly 1 item + /// Represents linked items element limited to a single type with exactly 1 item /// public static LinkedItemsElementMetadataModel SingleAllowedTypeExactlySingleItem = GenerateSingleAllowedTypeExactlySingleItem(); /// - /// Represents linked items element limited to multiple types with at least 1 at most or exactly 1 item + /// Represents linked items element limited to a single type with at most 1 item /// - public static LinkedItemsElementMetadataModel MultiAllowedTypesSingleItem = GenerateMultiAllowedTypesSingleItem(); + public static LinkedItemsElementMetadataModel SingleAllowedTypeAtMostSingleItem = GenerateSingleAllowedTypeAtMostSingleItem(); + + /// + /// Represents linked items element limited to multiple types with exactly 1 item + /// + public static LinkedItemsElementMetadataModel MultiAllowedTypesExactlySingleItem = GenerateMultiAllowedTypesExactlySingleItem(); + + /// + /// Represents linked items element limited to multiple types with at most 1 item + /// + public static LinkedItemsElementMetadataModel MultiAllowedTypesAtMostSingleItem = GenerateMultiAllowedTypesAtMostSingleItem(); /// /// Represents linked items element limited to multiple types with at least 1 item @@ -62,7 +72,17 @@ private static LinkedItemsElementMetadataModel GenerateSingleAllowedTypeExactlyS return singleAllowedTypeExactlySingleItem; } - private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesSingleItem() + private static LinkedItemsElementMetadataModel GenerateSingleAllowedTypeAtMostSingleItem() + { + var singleAllowedTypeExactlySingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6cccc-d984-45e8-8ebb-f6be25626ee8"), "modular_content_hero", ElementMetadataType.LinkedItems); + singleAllowedTypeExactlySingleItem.AllowedTypes = new List(new List { Reference.ById(HeroContentType.Id) }); + singleAllowedTypeExactlySingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + + return singleAllowedTypeExactlySingleItem; + } + + private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesExactlySingleItem() { var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "modular_content_blog", ElementMetadataType.LinkedItems); @@ -76,6 +96,20 @@ private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesSingleIt return multiAllowedTypesSingleItem; } + private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesAtMostSingleItem() + { + var multiAllowedTypesSingleItem = (LinkedItemsElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("4fa6bad6-d984-45cc-8ebb-f6be25626ee9"), "modular_content_coffee", ElementMetadataType.LinkedItems); + multiAllowedTypesSingleItem.AllowedTypes = new List(new List + { + Reference.ById(HeroContentType.Id), + Reference.ById(ArticleContentType.Id) + }); + multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + + return multiAllowedTypesSingleItem; + } + private static LinkedItemsElementMetadataModel GenerateMultiAllowedTypesMultiItems() { var multiAllowedTypesMultiItems = (LinkedItemsElementMetadataModel)TestDataGenerator. diff --git a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs index e92e8bb2..a8209a75 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/TestHelpers/SubpagesContentTypeData.cs @@ -28,14 +28,24 @@ public static class SubpagesContentTypeData public static SubpagesElementMetadataModel SingleAllowedTypeMultiItems = GenerateSingleAllowedTypeMultiItems(); /// - /// Represents linked items element limited to a single type with at most or exactly 1 item + /// Represents linked items element limited to a single type with exactly 1 item /// public static SubpagesElementMetadataModel SingleAllowedTypeExactlySingleItem = GenerateSingleAllowedTypeExactlySingleItem(); /// - /// Represents linked items element limited to multiple types with at least 1 at most or exactly 1 item + /// Represents linked items element limited to a single type with at most 1 item /// - public static SubpagesElementMetadataModel MultiAllowedTypesSingleItem = GenerateMultiAllowedTypesSingleItem(); + public static SubpagesElementMetadataModel SingleAllowedTypeAtMostSingleItem = GenerateSingleAllowedTypeAtMostSingleItem(); + + /// + /// Represents linked items element limited to multiple types with exactly 1 item + /// + public static SubpagesElementMetadataModel MultiAllowedTypesExactlySingleItem = GenerateMultiAllowedTypesExactlySingleItem(); + + /// + /// Represents linked items element limited to multiple types with at most 1 item + /// + public static SubpagesElementMetadataModel MultiAllowedTypesAtMostSingleItem = GenerateMultiAllowedTypesAtMostSingleItem(); /// /// Represents linked items element limited to multiple types with at least 1 item @@ -62,7 +72,17 @@ private static SubpagesElementMetadataModel GenerateSingleAllowedTypeExactlySing return singleAllowedTypeExactlySingleItem; } - private static SubpagesElementMetadataModel GenerateMultiAllowedTypesSingleItem() + private static SubpagesElementMetadataModel GenerateSingleAllowedTypeAtMostSingleItem() + { + var singleAllowedTypeAtMostSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6bad6-2284-45e8-8ebb-f6be25626ee8"), "subpages_hero", ElementMetadataType.Subpages); + singleAllowedTypeAtMostSingleItem.AllowedContentTypes = new List(new List { Reference.ById(HeroContentType.Id) }); + singleAllowedTypeAtMostSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.Exactly, Value = 1 }; + + return singleAllowedTypeAtMostSingleItem; + } + + private static SubpagesElementMetadataModel GenerateMultiAllowedTypesExactlySingleItem() { var multiAllowedTypesSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. GenerateElementMetadataBase(Guid.Parse("8fa6bad6-d984-45e8-8ebb-f6be25626ee9"), "subpages_blog", ElementMetadataType.Subpages); @@ -76,6 +96,20 @@ private static SubpagesElementMetadataModel GenerateMultiAllowedTypesSingleItem( return multiAllowedTypesSingleItem; } + private static SubpagesElementMetadataModel GenerateMultiAllowedTypesAtMostSingleItem() + { + var multiAllowedTypesSingleItem = (SubpagesElementMetadataModel)TestDataGenerator. + GenerateElementMetadataBase(Guid.Parse("8fa6ccd6-d984-45e8-cccc-f6be25626ee9"), "subpages_coffee", ElementMetadataType.Subpages); + multiAllowedTypesSingleItem.AllowedContentTypes = new List(new List + { + Reference.ById(HeroContentType.Id), + Reference.ById(ArticleContentType.Id) + }); + multiAllowedTypesSingleItem.ItemCountLimit = new LimitModel { Condition = LimitType.AtMost, Value = 1 }; + + return multiAllowedTypesSingleItem; + } + private static SubpagesElementMetadataModel GenerateMultiAllowedTypesMultiItems() { var multiAllowedTypesMultiItems = (SubpagesElementMetadataModel)TestDataGenerator. From 5d554c4aa20e4c63c5d25c2a08165f391c932209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 16 Mar 2023 13:32:49 +0100 Subject: [PATCH 42/48] 90 fix naming of ExtendedDeliveryModels --- README.md | 2 +- .../Common/Property.cs | 2 +- .../Configuration/CodeGeneratorOptions.cs | 4 +-- .../CodeGeneratorOptionsExtensions.cs | 6 ++-- .../Helpers/DeliveryElementHelper.cs | 2 +- .../Options/ArgHelpers.cs | 2 +- .../Options/ArgMappingsRegister.cs | 2 +- .../appSettings.json | 2 +- .../ArgHelpersTests.cs | 2 +- .../Common/ClassCodeGeneratorFactoryTests.cs | 4 +-- .../CodeGeneratorOptionsExtensionsTests.cs | 36 +++++++++---------- .../ExtendedDeliveryCodeGeneratorTests.cs | 18 +++++----- .../TypedDeliveryPropertyMapperTests.cs | 26 +++++++------- .../ValidationExtensionsTests.cs | 10 +++--- 14 files changed, 59 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 9f16fc95..96e6a9db 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ To learn how to generate executables for your favorite target platform, follow t | `-s` | `--structuredmodel` | False | `null` | For detailed please see [section](https://github.com/kontent-ai/model-generator-net#structured-model) | | `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | | `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | -| `-e` | `--extendeddelivermodels` | False | `false` | Indicates whether extended deliver models should be generated | +| `-e` | `--extendeddeliverymodels` | False | `false` | Indicates whether extended deliver models should be generated | #### Structured model diff --git a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs index 895115fe..98ee45d6 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Common/Property.cs @@ -93,7 +93,7 @@ public Property(string codename, string typeName, string id = null) public static bool IsModularContentElementType(string elementType) => elementType == ModularContentElementType; - public static bool IsContentTypeSupported(string elementType, bool extendedDeliverModels) => extendedDeliverModels + public static bool IsContentTypeSupported(string elementType, bool extendedDeliveryModels) => extendedDeliveryModels ? ExtendedDeliverElementTypesDictionary.ContainsKey(elementType) : DeliverElementTypesDictionary.ContainsKey(elementType); diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs index 8aa12ec3..9d2010c5 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptions.cs @@ -8,7 +8,7 @@ namespace Kontent.Ai.ModelGenerator.Core.Configuration; public class CodeGeneratorOptions { private const char StructuredModelSeparator = ','; - private const bool DefaultExtendedDeliverModels = false; + private const bool DefaultExtendedDeliveryModels = false; private const bool DefaultGeneratePartials = true; private const bool DefaultWithTypeProvider = true; private const bool DefaultManagementApi = false; @@ -28,7 +28,7 @@ public class CodeGeneratorOptions /// /// Indicates whether the extended Delivery models should be generated /// - public bool ExtendedDeliverModels { get; set; } = DefaultExtendedDeliverModels; + public bool ExtendedDeliveryModels { get; set; } = DefaultExtendedDeliveryModels; /// /// Namespace name of the generated classes diff --git a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs index f485a940..890e7881 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Configuration/CodeGeneratorOptionsExtensions.cs @@ -3,10 +3,10 @@ public static class CodeGeneratorOptionsExtensions { public static bool ManagementApi(this CodeGeneratorOptions options) => - options.ManagementApi && !options.ExtendedDeliverModels; + options.ManagementApi && !options.ExtendedDeliveryModels; public static bool ExtendedDeliveryModels(this CodeGeneratorOptions options) => - !options.ManagementApi && options.ExtendedDeliverModels; + !options.ManagementApi && options.ExtendedDeliveryModels; public static bool DeliveryApi(this CodeGeneratorOptions options) => !options.ManagementApi() && !options.ExtendedDeliveryModels(); @@ -21,7 +21,7 @@ public static DesiredModelsType GetDesiredModelsType(this CodeGeneratorOptions o } public static string GetProjectId(this CodeGeneratorOptions options) => - options.ManagementApi || options.ExtendedDeliverModels + options.ManagementApi || options.ExtendedDeliveryModels ? options.ManagementOptions.ProjectId : options.DeliveryOptions.ProjectId; diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs index d18e5d9f..71ed8740 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/DeliveryElementHelper.cs @@ -23,7 +23,7 @@ public static string GetElementType(CodeGeneratorOptions options, string element { elementType += Property.StructuredSuffix; } - else if (!options.ExtendedDeliverModels && options.IsStructuredModelModularContent() && Property.IsModularContentElementType(elementType)) + else if (!options.ExtendedDeliveryModels && options.IsStructuredModelModularContent() && Property.IsModularContentElementType(elementType)) { elementType += Property.StructuredSuffix; } diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index 04d01d85..e6e213a6 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -55,7 +55,7 @@ public static bool ContainsValidArgs(string[] args) private static IDictionary GetSpecificSwitchMappings(string[] args) { var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); - var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliverModels))); + var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliveryModels))); for (var i = 0; i < args.Length; i++) { diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs index ea7f6fa7..3591a9ef 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgMappingsRegister.cs @@ -33,7 +33,7 @@ internal class ArgMappingsRegister { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) }, { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, - { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) } + { "-e", nameof(CodeGeneratorOptions.ExtendedDeliveryModels) } }; public static readonly IDictionary ManagementMappings = new Dictionary diff --git a/src/Kontent.Ai.ModelGenerator/appSettings.json b/src/Kontent.Ai.ModelGenerator/appSettings.json index dca6107d..007f5bbd 100644 --- a/src/Kontent.Ai.ModelGenerator/appSettings.json +++ b/src/Kontent.Ai.ModelGenerator/appSettings.json @@ -16,7 +16,7 @@ }, // Indicates whether the extended Delivery models should be generated - "ExtendedDeliverModels": false, + "ExtendedDeliveryModels": false, // Namespace name of the generated classes "Namespace": null, diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index 38d7afc6..b635be48 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -49,7 +49,7 @@ public class ArgHelpersTests { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) }, { "-k", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, { "--apikey", $"{nameof(ManagementOptions)}:{nameof(ManagementOptions.ApiKey)}" }, - { "-e", nameof(CodeGeneratorOptions.ExtendedDeliverModels) } + { "-e", nameof(CodeGeneratorOptions.ExtendedDeliveryModels) } }; private static IDictionary ExpectedDeliveryMappings => new Dictionary diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs index b84fc11f..a274c04e 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Common/ClassCodeGeneratorFactoryTests.cs @@ -74,7 +74,7 @@ public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_NoCustom var codeGeneratorOptions = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); @@ -143,7 +143,7 @@ public void CreateClassCodeGenerator_ExtendedDeliveryClassCodeGenerator_CustomNa { ManagementApi = false, Namespace = customNamespace, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = ClassCodeGeneratorFactory.CreateClassCodeGenerator(codeGeneratorOptions, new ClassDefinition(classDefinitionCodename), classFileName); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs index ebedc0e8..cc263c73 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Configuration/CodeGeneratorOptionsExtensionsTests.cs @@ -142,7 +142,7 @@ public void ManagementApi_ManagementApi_ReturnsTrue() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var result = options.ManagementApi(); @@ -153,12 +153,12 @@ public void ManagementApi_ManagementApi_ReturnsTrue() [Theory] [InlineData(true)] [InlineData(false)] - public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliverModels) + public void ManagementApi_NotManagementApi_ReturnsFalse(bool extendedDeliveryModels) { var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = extendedDeliverModels + ExtendedDeliveryModels = extendedDeliveryModels }; var result = options.ManagementApi(); @@ -174,7 +174,7 @@ public void ManagementApi_InvalidConfig_ReturnsFalse(bool managementApi) var options = new CodeGeneratorOptions { ManagementApi = managementApi, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = options.ManagementApi(); @@ -185,12 +185,12 @@ public void ManagementApi_InvalidConfig_ReturnsFalse(bool managementApi) [Theory] [InlineData(true)] [InlineData(false)] - public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extendedDeliverModels) + public void ExtendedDeliveryModels_ManagementApiIsTrue_ReturnsFalse(bool extendedDeliveryModels) { var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = extendedDeliverModels + ExtendedDeliveryModels = extendedDeliveryModels }; var result = options.ExtendedDeliveryModels(); @@ -204,7 +204,7 @@ public void ExtendedDeliveryModels_ManagementApiIsFalse_ExtendedDeliveryOptionsI var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var result = options.ExtendedDeliveryModels(); @@ -218,7 +218,7 @@ public void ExtendedDeliveryModels_ManagementApiIsFalse_ReturnsTrue() var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = options.ExtendedDeliveryModels(); @@ -242,7 +242,7 @@ public void DeliveryApi_ManagementApiIsFalse_ExtendedDeliveryOptionsIsFalse_Retu var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var result = options.DeliveryApi(); @@ -256,7 +256,7 @@ public void DeliveryApi_ManagementApi_ReturnsFalse() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var result = options.DeliveryApi(); @@ -270,7 +270,7 @@ public void DeliveryApi_ExtendedDeliveryOptions_ReturnsFalse() var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = options.DeliveryApi(); @@ -284,7 +284,7 @@ public void DeliveryApi_ManagementApiIsTrue_ExtendedDeliveryOptionsIsTrue_Return var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = options.DeliveryApi(); @@ -298,7 +298,7 @@ public void GetDesiredModelsType_ManagementApi_ReturnsManagement() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var result = options.GetDesiredModelsType(); @@ -312,7 +312,7 @@ public void GetDesiredModelsType_ExtendedDeliveryModels_ReturnsExtendedDelivery( var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; var result = options.GetDesiredModelsType(); @@ -326,7 +326,7 @@ public void GetDesiredModelsType_ManagementApiIsFalse_ExtendedDeliveryOptionsIsF var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var result = options.GetDesiredModelsType(); @@ -352,7 +352,7 @@ public void GetProjectId_DeliveryApi_Returns() var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false, + ExtendedDeliveryModels = false, DeliveryOptions = new DeliveryOptions { ProjectId = projectId @@ -372,7 +372,7 @@ public void GetProjectId_ManagementApi_Returns() var options = new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = false, + ExtendedDeliveryModels = false, ManagementOptions = new ManagementOptions { ProjectId = projectId @@ -392,7 +392,7 @@ public void GetProjectId_ExtendedDeliveryModels_Returns() var options = new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true, + ExtendedDeliveryModels = true, ManagementOptions = new ManagementOptions { ProjectId = projectId diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs index 5c8c747c..558827b8 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ExtendedDeliveryCodeGeneratorTests.cs @@ -46,20 +46,20 @@ public void Constructor_ManagementIsTrue_Throws() mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = true, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }); Creator(mockOptions.Object).Should().Throw(); } [Fact] - public void Constructor_ExtendedDeliverModelsIsFalse_Throws() + public void Constructor_ExtendedDeliveryModelsIsFalse_Throws() { var mockOptions = new Mock>(); mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }); Creator(mockOptions.Object).Should().Throw(); @@ -72,7 +72,7 @@ public void Constructor_CreatesInstance() mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }); var extendedDeliveryCodeGenerator = new ExtendedDeliveryCodeGenerator(mockOptions.Object, _outputProvider, _managementClient); @@ -89,7 +89,7 @@ public void GetClassCodeGenerators_ExtendedDeliverPreviewModelsIsFalse_Returns(S mockOptions.SetupGet(option => option.Value).Returns(new CodeGeneratorOptions { ManagementApi = false, - ExtendedDeliverModels = true, + ExtendedDeliveryModels = true, StructuredModel = structuredModel.ToString() }); @@ -201,7 +201,7 @@ public async Task IntegrationTest_RunAsync_CorrectFiles(StructuredModelFlags str var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - ExtendedDeliverModels = true, + ExtendedDeliveryModels = true, Namespace = "CustomNamespace", OutputDir = TempDir, ManagementApi = false, @@ -233,7 +233,7 @@ public async Task IntegrationTest_RunAsync_GeneratedSuffix_CorrectFiles(Structur var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - ExtendedDeliverModels = true, + ExtendedDeliveryModels = true, Namespace = "CustomNamespace", OutputDir = TempDir, ManagementApi = false, @@ -268,7 +268,7 @@ public async Task IntegrationTest_RunAsync_GeneratePartials_CorrectFiles(Structu var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - ExtendedDeliverModels = true, + ExtendedDeliveryModels = true, Namespace = "CustomNamespace", OutputDir = TempDir, ManagementApi = false, @@ -313,7 +313,7 @@ public async Task IntegrationTest_RunAsync_TypeProvider_CorrectFiles(StructuredM var mockOptions = new Mock>(); mockOptions.Setup(x => x.Value).Returns(new CodeGeneratorOptions { - ExtendedDeliverModels = true, + ExtendedDeliveryModels = true, Namespace = "CustomNamespace", OutputDir = TempDir, ManagementApi = false, diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index d9e8e391..ed4a8071 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -14,9 +14,9 @@ namespace Kontent.Ai.ModelGenerator.Tests.Helpers; public class TypedDeliveryPropertyMapperTests { - private static readonly CodeGeneratorOptions ExtendedDeliverModelsOptions = new CodeGeneratorOptions + private static readonly CodeGeneratorOptions ExtendedDeliveryModelsOptions = new CodeGeneratorOptions { - ExtendedDeliverModels = true + ExtendedDeliveryModels = true }; [Fact] @@ -27,7 +27,7 @@ public void TryMap_ElementIsNull_Throws() new ContentTypeModel() }; - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, ExtendedDeliverModelsOptions, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(null, contentTypes, ExtendedDeliveryModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -41,7 +41,7 @@ public void TryMap_NotLinkedItemsElementOrSubpages_Throws() }; var element = new AssetElementMetadataModel(); - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, ExtendedDeliverModelsOptions, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, ExtendedDeliveryModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -50,7 +50,7 @@ public void TryMap_NotLinkedItemsElementOrSubpages_Throws() [MemberData(nameof(GetBasicAllowedElements))] public void TryMap_ContentTypesIsNull_Throws(ElementMetadataBase element) { - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, null, ExtendedDeliverModelsOptions, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, null, ExtendedDeliveryModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -61,7 +61,7 @@ public void TryMap_ContentTypesIsEmpty_Throws(ElementMetadataBase element) { var contentTypes = new List(); - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, ExtendedDeliverModelsOptions, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, ExtendedDeliveryModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -90,7 +90,7 @@ public void TryMap_GeneralExtendedDeliveryModelsIsFalse_Throws(ElementMetadataBa }; var options = new CodeGeneratorOptions { - ExtendedDeliverModels = false + ExtendedDeliveryModels = false }; var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, contentTypes, options, out _); @@ -117,7 +117,7 @@ public void TryMap_Live_CouldNotFindAllowedType_Throws(ElementMetadataBase eleme } }; - var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliverModelsOptions, out _); + var tryMapCall = () => TypedDeliveryPropertyMapper.TryMap(element, allContentTypes, ExtendedDeliveryModelsOptions, out _); tryMapCall.Should().ThrowExactly(); } @@ -140,7 +140,7 @@ public void TryMap_Live_SingleAllowedTypeMultiItems_Returns(List Date: Thu, 16 Mar 2023 14:49:08 +0100 Subject: [PATCH 43/48] 90 docs --- README.md | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 96e6a9db..b35cbda1 100644 --- a/README.md +++ b/README.md @@ -47,21 +47,20 @@ To learn how to generate executables for your favorite target platform, follow t ### Delivery API parameters -| Short key | Long key | Required | Default value | Description | -| --------- | :-------------------------------------: | :------: | :---------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID | -| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) | -| `-o` | `--outputdir` | False | `\.` | An output folder path | -| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. | -| `-t` | `--withtypeprovider` | False | `true` | Indicates whether the `CustomTypeProvider` class should be generated (see [Customizing the strong-type binding logic](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/strongly-typed-models.md#customizing-the-strong-type-binding-logic) for more info) | -| `-s` | `--structuredmodel` | False | `null` | For detailed please see [section](https://github.com/kontent-ai/model-generator-net#structured-model) | -| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | -| `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | -| `-e` | `--extendeddeliverymodels` | False | `false` | Indicates whether extended deliver models should be generated | - -#### Structured model - -Generates `IRichTextContent` instead of `string` for rich-text elements or `IDateTimeContent` instead of `DateTime?` for date-time elements. This enables utilizing [structured rich-text rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md) [structured date-time rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md). For *modular content elements* and *subpages* generates [`IContentItem`](https://github.com/kontent-ai/delivery-sdk-net/blob/master/Kontent.Ai.Delivery.Abstractions/ContentItems/IContentItem.cs) instead of `object`, the model also implements the interface `IContentItem`. Allowed values [`RichText`, `DateTime`, `True`, `ModularContent`], as a separator you should use `,`. ⚠️ `True` parameter is **obsolete** and interprets the same value as `RichText`. +| Short key | Long key | Required | Default value | Description | +| --------- | :--------------------------------------: | :------: | :---------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| `-p` | `--projectid` | True | `null` | A GUID that can be found in [Kontent](https://app.kontent.ai) -> API keys -> Project ID | +| `-n` | `--namespace` | False | `KontentAiModels` | A name of the [C# namespace](https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx) | +| `-o` | `--outputdir` | False | `\.` | An output folder path | +| `-g` | `--generatepartials` | False | `true` | Generates partial classes for customization. Partial classes are the best practice for customization so the recommended value is `true`. | +| `-t` | `--withtypeprovider` | False | `true` | Indicates whether the `CustomTypeProvider` class should be generated (see [Customizing the strong-type binding logic](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/strongly-typed-models.md#customizing-the-strong-type-binding-logic) for more info) | +| `-s` | `--structuredmodel` | False | `null` | Allowed values [`RichText`, `DateTime`, `True`, `ModularContent`], as a separator you should use `,`. ⚠️ `True` parameter is **obsolete** and interprets the same value as `RichText`. For further details see [structured models rendering](https://github.com/kontent-ai/delivery-sdk-net/blob/master/docs/customization-and-extensibility/structured-models/structured-models-rendering.md) | +| `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | +| `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | +| `-e` | `--extendeddeliverymodels` | False | `false` | Indicates whether extended deliver models should be generated | +| `-k` | `--apikey` | True | `null` | Can be used with the extended delivery moedels. For details please see [Management API parameters section](#management-api-parameters) | + +For advanced configuration please see [Advanced configuration (Preview API, Secure API)](#advanced-configuration-preview-api-secure-api) ### CLI Syntax @@ -122,6 +121,7 @@ public partial class Home : IContentItem public const string SingleAllowedTypeSingleLinkedContentItemCodename = "single_allowed_type_single_linked_content_item"; public const string SingleAllowedTypeMultiLinkedContentItemsCodename = "single_allowed_type_multi_linked_content_items"; public const string MultiAllowedTypesSingleLinkedContentItemCodename = "multi_allowed_types_single_linked_content_item"; + public const string MultiAllowedTypesAtMostSingleLinkedContentItemCodename = "multi_allowed_types_at-most_single_linked_content_item"; public const string MultiAllowedTypesMultiLinkedContentItemsCodename = "multi_allowed_types_multi_linked_content_items"; // Allowed Content Types == "Article" && Limit number of items <= 1 @@ -134,7 +134,10 @@ public partial class Home : IContentItem public IEnumerable SingleAllowedTypeMultiLinkedContentItems { get; set; } // Allowed Content Types number > 1 && Limit number of items == 1 - public IEnumerable MultiAllowedTypesSingleLinkedContentItem { get; set; } + public IEnumerable MultiAllowedTypesExactlySingleLinkedContentItem { get; set; } + + // Allowed Content Types number > 1 && Limit number of items <= 1 + public IEnumerable MultiAllowedTypesAtMostSingleLinkedContentItem { get; set; } // Allowed Content Types number > 1 && Limit number of items > 1 public IEnumerable MultiAllowedTypesMultiLinkedContentItems { get; set; } From 546327e15952d7a3478ed3c30e3ffc87a2c92f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 24 Mar 2023 14:18:35 +0100 Subject: [PATCH 44/48] 90 fix warnings --- .../Options/ArgHelpers.cs | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index e6e213a6..cb361a2a 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using Kontent.Ai.Delivery.Abstractions; @@ -10,9 +11,14 @@ namespace Kontent.Ai.ModelGenerator.Options; internal static class ArgHelpers { - private static readonly ProgramOptionsData ManagementProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), "management-sdk-net"); - private static readonly ProgramOptionsData DeliveryProgramOptionsData = new ProgramOptionsData(typeof(DeliveryOptions), "delivery-sdk-net"); - private static readonly ProgramOptionsData ExtendedDeliveryProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), typeof(DeliveryOptions), "delivery-sdk-net"); + private static readonly ProgramOptionsData ManagementProgramOptionsData = + new ProgramOptionsData(typeof(ManagementOptions), "management-sdk-net"); + + private static readonly ProgramOptionsData DeliveryProgramOptionsData = + new ProgramOptionsData(typeof(DeliveryOptions), "delivery-sdk-net"); + + private static readonly ProgramOptionsData ExtendedDeliveryProgramOptionsData = + new ProgramOptionsData(typeof(ManagementOptions), typeof(DeliveryOptions), "delivery-sdk-net"); public static IDictionary GetSwitchMappings(string[] args) => ArgMappingsRegister.GeneralMappings .Union(GetSpecificSwitchMappings(args)) @@ -75,22 +81,26 @@ private static IDictionary GetSpecificSwitchMappings(string[] ar return ArgMappingsRegister.DeliveryMappings; } - private static bool IsOptionPropertyValid(ProgramOptionsData programOptionsData, string arg) => - IsOptionPropertyValid(programOptionsData.OptionProperties.Select(prop => $"{programOptionsData.OptionsName}:{prop.Name}"), arg); + private static bool IsOptionPropertyValid<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T> + (ProgramOptionsData programOptionsData, string arg) => + IsOptionPropertyValid(programOptionsData.OptionProperties.Select(prop => $"{programOptionsData.OptionsName}:{prop.Name}"), arg); private static bool IsOptionPropertyValid(IEnumerable optionProperties, string arg) => optionProperties.Any(prop => GetPrefixedMappingName(prop, false) == arg); private static string GetPrefixedMappingName(string mappingName, bool toLower = true) => $"--{(toLower ? mappingName.ToLower() : mappingName)}"; - private class ProgramOptionsData + private class ProgramOptionsData<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T> { public IEnumerable OptionProperties { get; } public string OptionsName { get; } public UsedSdkInfo UsedSdkInfo { get; set; } public Type Type { get; } - public ProgramOptionsData(Type type, string sdkName) + public ProgramOptionsData( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] + Type type, + string sdkName) { UsedSdkInfo = new UsedSdkInfo(type, sdkName); Type = type; @@ -98,7 +108,11 @@ public ProgramOptionsData(Type type, string sdkName) OptionsName = type.Name; } - public ProgramOptionsData(Type optionsType, Type sdkType, string sdkName) + public ProgramOptionsData( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] + Type optionsType, + Type sdkType, + string sdkName) { UsedSdkInfo = new UsedSdkInfo(sdkType, sdkName); Type = optionsType; From 540972244a22076b4a76f83a41d696240c47cfac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Fri, 31 Mar 2023 14:33:55 +0200 Subject: [PATCH 45/48] 90 docx fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b35cbda1..4a977129 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ To learn how to generate executables for your favorite target platform, follow t | `-f` | `--filenamesuffix` | False | `null` | Adds a suffix to generated filenames (e.g., News.cs becomes News.Generated.cs) | | `-b` | `--baseclass` | False | `null` | If provided, a base class type will be created and all generated classes will derive from that base class via partial extender classes | | `-e` | `--extendeddeliverymodels` | False | `false` | Indicates whether extended deliver models should be generated | -| `-k` | `--apikey` | True | `null` | Can be used with the extended delivery moedels. For details please see [Management API parameters section](#management-api-parameters) | +| `-k` | `--apikey` | True | `null` | Can be used with the extended delivery models. For details please see [Management API parameters section](#management-api-parameters) | For advanced configuration please see [Advanced configuration (Preview API, Secure API)](#advanced-configuration-preview-api-secure-api) From d4ad7bd6d98a50c15275a02f880a36738eb43b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 6 Apr 2023 15:19:29 +0200 Subject: [PATCH 46/48] 90 fix condition for itemcountlimit --- .../Helpers/TypedDeliveryPropertyMapper.cs | 15 +++++++++++---- .../Helpers/TypedDeliveryPropertyMapperTests.cs | 9 +++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs index 042b34c3..046c80b6 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs +++ b/src/Kontent.Ai.ModelGenerator.Core/Helpers/TypedDeliveryPropertyMapper.cs @@ -22,8 +22,7 @@ public static bool TryMap( var elementOptions = GetElementOptions(el); - if (!elementOptions.AllowedTypes.Any() || - elementOptions.AllowedTypes.Count() > 1) + if (!IsAllowedContentTypesOptionSupported(elementOptions.AllowedTypes)) { typedProperty = null; return false; @@ -32,8 +31,7 @@ public static bool TryMap( var allowedContentType = GetAllowedContentType(elementOptions.AllowedTypes.First().Id.Value, contentTypes); var allowedContentTypeCodename = TextHelpers.GetValidPascalCaseIdentifierName(allowedContentType.Codename); - if (elementOptions.ItemCountLimit.Value == 1 && - (elementOptions.ItemCountLimit.Condition is LimitType.Exactly or LimitType.AtMost)) + if (IsItemCountLimitOptionSupported(elementOptions.ItemCountLimit)) { typedProperty = Property.FromContentTypeElement(el, allowedContentTypeCodename); return true; @@ -71,6 +69,15 @@ private static void Validate(List contentTypes, ElementMetadat } } + private static bool IsAllowedContentTypesOptionSupported(IEnumerable allowedTypes) => + allowedTypes != null && allowedTypes.Count() == 1; + + private static bool IsItemCountLimitOptionSupported(LimitModel itemCountLimit) => itemCountLimit is + { + Value: 1, + Condition: LimitType.Exactly or LimitType.AtMost + }; + private static ContentTypeModel GetAllowedContentType(Guid allowedTypeId, List contentTypes) { var allowedType = contentTypes.FirstOrDefault(type => allowedTypeId == type.Id); diff --git a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs index ed4a8071..d6376665 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/Helpers/TypedDeliveryPropertyMapperTests.cs @@ -327,6 +327,15 @@ public static IEnumerable GetSingleAllowedTypeMultiItems() limitModel, linkedContentTypeModels.Select(ct => ct.Id)) }; + yield return new object[] + { + linkedContentTypeModels, + TestDataGenerator.GenerateSubpagesElement( + Guid.NewGuid().ToString(), + "just_articles", + null, + linkedContentTypeModels.Select(ct => ct.Id)) + }; } public static IEnumerable GetSingleAllowedTypeExactlySingleItem() From 07ad4ca88c20d67caa8d854bee40b171ad3f4bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 13 Apr 2023 13:03:38 +0200 Subject: [PATCH 47/48] 90 fix arg problems --- .../Options/ArgHelpers.cs | 56 +++-- .../ArgHelpersTests.cs | 210 ++++++++++-------- 2 files changed, 156 insertions(+), 110 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs index cb361a2a..3b2926c8 100644 --- a/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs +++ b/src/Kontent.Ai.ModelGenerator/Options/ArgHelpers.cs @@ -11,6 +11,9 @@ namespace Kontent.Ai.ModelGenerator.Options; internal static class ArgHelpers { + private const char NameAndValueSeparator = '='; + private const char NamePrefix = '-'; + private static readonly ProgramOptionsData ManagementProgramOptionsData = new ProgramOptionsData(typeof(ManagementOptions), "management-sdk-net"); @@ -35,13 +38,19 @@ public static bool ContainsValidArgs(string[] args) .Select(p => p.Name.ToLower()) .ToList(); - foreach (var arg in args.Where(a => - a.StartsWith('-') && - !ArgMappingsRegister.AllMappingsKeys.Contains(a) && - !IsOptionPropertyValid(ManagementProgramOptionsData, a) && - !IsOptionPropertyValid(DeliveryProgramOptionsData, a) && - !IsOptionPropertyValid(ExtendedDeliveryProgramOptionsData, a) && - !IsOptionPropertyValid(codeGeneratorOptionsProperties, a))) + var brokenArgs = args.Where(a => + { + if (!StartsWithArgumentName(a)) return false; + + var argumentName = SplitArgument(a).FirstOrDefault(); + return !ArgMappingsRegister.AllMappingsKeys.Contains(argumentName) && + !IsOptionPropertyValid(ManagementProgramOptionsData, argumentName) && + !IsOptionPropertyValid(DeliveryProgramOptionsData, argumentName) && + !IsOptionPropertyValid(ExtendedDeliveryProgramOptionsData, argumentName) && + !IsOptionPropertyValid(codeGeneratorOptionsProperties, argumentName); + }); + + foreach (var arg in brokenArgs) { Console.Error.WriteLine($"Unsupported parameter: {arg}"); containsValidArgs = false; @@ -60,19 +69,36 @@ public static bool ContainsValidArgs(string[] args) private static IDictionary GetSpecificSwitchMappings(string[] args) { - var managementDecidingArgs = new DecidingArgs("-m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); - var extendedDeliverDecidingArgs = new DecidingArgs("-e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliveryModels))); + var managementDecidingArgs = new DecidingArgs("m", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ManagementApi))); + var extendedDeliverDecidingArgs = new DecidingArgs("e", GetPrefixedMappingName(nameof(CodeGeneratorOptions.ExtendedDeliveryModels))); for (var i = 0; i < args.Length; i++) { - if (i + 1 >= args.Length || args[i + 1] != "true") continue; + if (!StartsWithArgumentName(args[i])) continue; - if (args[i] == managementDecidingArgs.ShorthandedArgName || args[i] == managementDecidingArgs.FullArgName) + string argValue, argName; + if (args[i].Contains(NameAndValueSeparator)) + { + var argPair = SplitArgument(args[i]); + + argName = argPair[0]; + argValue = argPair[1]; + } + else + { + argName = args[i]; + argValue = args[i + 1]; + } + + if (!bool.TrueString.Equals(argValue, StringComparison.OrdinalIgnoreCase)) + continue; + + if (argName == managementDecidingArgs.ShorthandedArgName || argName == managementDecidingArgs.FullArgName) { return ArgMappingsRegister.ManagementMappings; } - if (args[i] == extendedDeliverDecidingArgs.ShorthandedArgName || args[i] == extendedDeliverDecidingArgs.FullArgName) + if (argName == extendedDeliverDecidingArgs.ShorthandedArgName || argName == extendedDeliverDecidingArgs.FullArgName) { return ArgMappingsRegister.ExtendedDeliveryMappings; } @@ -90,6 +116,10 @@ private static bool IsOptionPropertyValid(IEnumerable optionProperties, private static string GetPrefixedMappingName(string mappingName, bool toLower = true) => $"--{(toLower ? mappingName.ToLower() : mappingName)}"; + private static string[] SplitArgument(string arg) => arg.Split(NameAndValueSeparator); + + private static bool StartsWithArgumentName(string arg) => arg.StartsWith(NamePrefix); + private class ProgramOptionsData<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T> { public IEnumerable OptionProperties { get; } @@ -128,7 +158,7 @@ private class DecidingArgs public DecidingArgs(string shorthandedArgName, string fullArgName) { - ShorthandedArgName = shorthandedArgName; + ShorthandedArgName = $"{NamePrefix}{shorthandedArgName}"; FullArgName = fullArgName; } } diff --git a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs index b635be48..78951795 100644 --- a/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs +++ b/test/Kontent.Ai.ModelGenerator.Tests/ArgHelpersTests.cs @@ -65,89 +65,37 @@ public class ArgHelpersTests { "-t", nameof(CodeGeneratorOptions.WithTypeProvider) } }; - [Fact] - public void GetSwitchMappings_MissingMapiSwitch_ReturnsDeliveryMappings() - { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString() - }); - - result.Should().BeEquivalentTo(ExpectedDeliveryMappings); - } - - [Fact] - public void GetSwitchMappings_MapiSwitchIsFalse_ReturnsDeliveryMappings() + [Theory] + [MemberData(nameof(DeliveryApiSwitchOptions))] + public void GetSwitchMappings_DeliveryApiSwitchOptions_ReturnsDeliveryMappings(string[] args) { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-m", - "false" - }); + var result = ArgHelpers.GetSwitchMappings(args); result.Should().BeEquivalentTo(ExpectedDeliveryMappings); } - [Fact] - public void GetSwitchMappings_MapiSwitchIsTrue_ReturnsManagementMappings() + [Theory] + [MemberData(nameof(MapiSwitchOptions))] + public void GetSwitchMappings_MapiSwitchOptions_ReturnsManagementMappings(string[] args) { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-m", - "true" - }); + var result = ArgHelpers.GetSwitchMappings(args); result.Should().BeEquivalentTo(ExpectedManagementMappings); } - [Fact] - public void GetSwitchMappings_ExtendedDeliveryIsTrue_ReturnsManagementMappings() - { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-e", - "true" - }); - - result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); - } - - [Fact] - public void GetSwitchMappings_ExtendedDeliveryAndPreviewIsTrue_ReturnsManagementMappings() + [Theory] + [MemberData(nameof(ExtendedDeliveryApiSwitchOptions))] + public void GetSwitchMappings_ExtendedDeliveryApiSwitchOptions_ReturnsManagementMappings(string[] args) { - var result = ArgHelpers.GetSwitchMappings(new string[] - { - "-p", - Guid.NewGuid().ToString(), - "-e", - "true", - "-r", - "true" - }); + var result = ArgHelpers.GetSwitchMappings(args); result.Should().BeEquivalentTo(ExpectedExtendedDeliveryMappings); } - [Fact] - public void ContainsContainsValidArgs_SupportedDeliveryOptions_ReturnsTrue() + [Theory] + [MemberData(nameof(SupportedDeliveryOptions))] + public void ContainsContainsValidArgs_SupportedDeliveryOptions_ReturnsTrue(string[] args) { - var args = AppendValuesToArgs(ExpectedDeliveryMappings) - .Concat(AppendValuesToArgs(ToLower(new List - { - nameof(CodeGeneratorOptions.StructuredModel), - nameof(CodeGeneratorOptions.WithTypeProvider) - }))) - .Concat(AppendValuesToArgs(GeneralOptionArgs)) - .Concat(AppendValuesToArgs(typeof(DeliveryOptions))) - .ToArray(); - var result = ArgHelpers.ContainsValidArgs(args); result.Should().BeTrue(); @@ -170,18 +118,10 @@ public void ContainsContainsValidArgs_UnsupportedDeliveryOptions_ReturnsFalse(st result.Should().BeFalse(); } - [Fact] - public void ContainsContainsValidArgs_SupportedManagementOptions_ReturnsTrue() + [Theory] + [MemberData(nameof(SupportedManagementOptions))] + public void ContainsContainsValidArgs_SupportedManagementOptions_ReturnsTrue(string[] args) { - var args = AppendValuesToArgs(ExpectedManagementMappings) - .Concat(AppendValuesToArgs(ToLower(new List - { - nameof(CodeGeneratorOptions.ManagementApi) - }))) - .Concat(AppendValuesToArgs(GeneralOptionArgs)) - .Concat(AppendValuesToArgs(typeof(ManagementOptions))) - .ToArray(); - var result = ArgHelpers.ContainsValidArgs(args); result.Should().BeTrue(); @@ -205,19 +145,10 @@ public void ContainsContainsValidArgs_UnsupportedManagementOptions_ReturnsFalse( result.Should().BeFalse(); } - [Fact] - public void ContainsContainsValidArgs_SupportedExtendedDeliveryOptions_ReturnsTrue() + [Theory] + [MemberData(nameof(SupportedExtendedDeliveryOptions))] + public void ContainsContainsValidArgs_SupportedExtendedDeliveryOptions_ReturnsTrue(string[] args) { - var args = AppendValuesToArgs(ExpectedExtendedDeliveryMappings) - .Concat(AppendValuesToArgs(ToLower(new List - { - nameof(CodeGeneratorOptions.StructuredModel), - nameof(CodeGeneratorOptions.WithTypeProvider) - }))) - .Concat(AppendValuesToArgs(GeneralOptionArgs)) - .Concat(AppendValuesToArgs(typeof(ManagementOptions))) - .ToArray(); - var result = ArgHelpers.ContainsValidArgs(args); result.Should().BeTrue(); @@ -268,22 +199,107 @@ public void GetProgramOptionsData_ExtendedDeliveryApi_ReturnsExtendedDeliveryPro AssertUsedSdkInfoResult(result, "delivery-sdk-net", typeof(DeliveryOptions)); } - private static IEnumerable AppendValuesToArgs(IDictionary mappings) => AppendValuesToArgs(mappings.Keys); + public static IEnumerable DeliveryApiSwitchOptions() + { + var projectId = Guid.NewGuid().ToString(); + + yield return new object[] { new string[] { "-p", projectId, "-m", "False" } }; + yield return new object[] { new string[] { "-p", projectId, "-m", "false" } }; + yield return new object[] { new string[] { "-p", projectId, "-m=false" } }; + yield return new object[] { new string[] { "-p", projectId, "-m=False" } }; + yield return new object[] { new string[] { "-p", projectId } }; + } + + public static IEnumerable MapiSwitchOptions() + { + var projectId = Guid.NewGuid().ToString(); + + yield return new object[] { new string[] { "-p", projectId, "-m", "True" } }; + yield return new object[] { new string[] { "-p", projectId, "-m", "true" } }; + yield return new object[] { new string[] { "-p", projectId, "-m=true" } }; + yield return new object[] { new string[] { "-p", projectId, "-m=True" } }; + } + + public static IEnumerable ExtendedDeliveryApiSwitchOptions() + { + var projectId = Guid.NewGuid().ToString(); + + yield return new object[] { new string[] { "-p", projectId, "-e", "True" } }; + yield return new object[] { new string[] { "-p", projectId, "-e", "true" } }; + yield return new object[] { new string[] { "-p", projectId, "-e=true" } }; + yield return new object[] { new string[] { "-p", projectId, "-e=True" } }; + } + + public static IEnumerable SupportedManagementOptions() + { + var args = AppendValuesToArgs(ExpectedManagementMappings) + .Concat(AppendValuesToArgs(ToLower(new List + { + nameof(CodeGeneratorOptions.ManagementApi) + }))) + .Concat(AppendValuesToArgs(GeneralOptionArgs)) + .Concat(AppendValuesToArgs(typeof(ManagementOptions))) + .ToArray(); + + foreach (var arg in args) + { + yield return new object[] { arg }; + } + } + + public static IEnumerable SupportedDeliveryOptions() + { + var args = AppendValuesToArgs(ExpectedDeliveryMappings) + .Concat(AppendValuesToArgs(ToLower(new List + { + nameof(CodeGeneratorOptions.StructuredModel), + nameof(CodeGeneratorOptions.WithTypeProvider) + }))) + .Concat(AppendValuesToArgs(GeneralOptionArgs)) + .Concat(AppendValuesToArgs(typeof(DeliveryOptions))) + .ToArray(); + + foreach (var arg in args) + { + yield return new object[] { arg }; + } + } + + public static IEnumerable SupportedExtendedDeliveryOptions() + { + var args = AppendValuesToArgs(ExpectedExtendedDeliveryMappings) + .Concat(AppendValuesToArgs(ToLower(new List + { + nameof(CodeGeneratorOptions.StructuredModel), + nameof(CodeGeneratorOptions.WithTypeProvider) + }))) + .Concat(AppendValuesToArgs(GeneralOptionArgs)) + .Concat(AppendValuesToArgs(typeof(ManagementOptions))) + .ToArray(); - private static IEnumerable AppendValuesToArgs(Type type) => + foreach (var arg in args) + { + yield return new object[] { arg }; + } + } + + private static IEnumerable> AppendValuesToArgs(IDictionary mappings) => AppendValuesToArgs(mappings.Keys); + + private static IEnumerable> AppendValuesToArgs(Type type) => AppendValuesToArgs(type.GetProperties().Select(p => $"{type.Name}:{p.Name}")); private static IEnumerable ToLower(IEnumerable args) => args.Select(a => a.ToLower()); - private static IEnumerable AppendValuesToArgs(IEnumerable args) + private static IEnumerable> AppendValuesToArgs(IEnumerable args) { - var argsWithValue = new List(); + var argValue = "arg_value"; foreach (var arg in args) { - argsWithValue.Add(arg.StartsWith('-') ? arg : $"--{arg}"); - argsWithValue.Add("arg_value"); + var argName = arg.StartsWith('-') ? arg : $"--{arg}"; + + yield return new List { argName, argValue }; + yield return new List { $"{argName}={argValue}" }; } - return argsWithValue; } private static void AssertUsedSdkInfoResult(UsedSdkInfo result, string expectedName, Type expectedType) From 6dfb80a1b317cbf735641e31f6551498ac702747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ev=C4=8D=C3=ADk?= Date: Thu, 13 Apr 2023 15:24:54 +0200 Subject: [PATCH 48/48] 90 bump nuget packages of Delivery and Management sdks --- .../Kontent.Ai.ModelGenerator.Core.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj b/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj index 08ea07f1..17eaa144 100644 --- a/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj +++ b/src/Kontent.Ai.ModelGenerator.Core/Kontent.Ai.ModelGenerator.Core.csproj @@ -25,14 +25,14 @@ - - + + - +