using Microsoft.TypeSpec.Generator.Input; using Microsoft.TypeSpec.Generator.Input.Extensions; using System.Collections.Generic; using System.Linq; namespace OpenAILibraryPlugin.Tests.Common { /// /// Provider methods to construct intput test data /// public static class InputFactory { /// /// Primitive input data types /// public static class Primitive { /// /// Construct string input data /// /// /// /// /// public static InputPrimitiveType String(string? name = null, string? crossLanguageDefinitionId = null, string? encode = null) { return new InputPrimitiveType(InputPrimitiveTypeKind.String, name ?? string.Empty, crossLanguageDefinitionId ?? string.Empty, encode); } } /// /// Construct input enum types /// public static class EnumMember { /// /// Construct input enum type value for int32 /// /// /// /// /// public static InputEnumTypeValue Int32(string name, int value, InputEnumType enumType) { return new InputEnumTypeValue(name, value, InputPrimitiveType.Int32, "", $"{name} description", enumType); } /// /// Construct input enum type value for float32 /// /// /// /// /// public static InputEnumTypeValue Float32(string name, float value, InputEnumType enumType) { return new InputEnumTypeValue(name, value, InputPrimitiveType.Float32, "", $"{name} description", enumType); } /// /// Construct input enum type value for string /// /// /// /// /// public static InputEnumTypeValue String(string name, string value, InputEnumType enumType) { return new InputEnumTypeValue(name, value, InputPrimitiveType.String, "", $"{name} description", enumType); } } /// /// Construct input literal types /// public static class Literal { /// /// Construct input literal type value for string /// /// /// /// /// public static InputLiteralType String(string value, string? name = null, string? @namespace = null) { return new InputLiteralType(name ?? string.Empty, @namespace ?? string.Empty, InputPrimitiveType.String, value); } /// /// Construct input enum type value for any /// /// /// /// /// public static InputLiteralType Int32(int value, string? name = null, string? @namespace = null) { return new InputLiteralType(name ?? string.Empty, @namespace ?? string.Empty, InputPrimitiveType.Int32, value); } } /// /// Construct input constants /// public static class Constant { /// /// Construct input constnat for string /// /// /// public static InputConstant String(string value) { return new InputConstant(value, InputPrimitiveType.String); } /// /// Construct input constnat for int64 /// /// /// public static InputConstant Int64(long value) { return new InputConstant(value, InputPrimitiveType.Int64); } } /// /// Construct input parameter with content type /// /// /// public static InputHeaderParameter ContentTypeParameter(string contentType) => HeaderParameter( "contentType", Literal.String(contentType), isRequired: true, defaultValue: Constant.String(contentType), serializedName: "Content-Type", isContentType: true, scope: InputParameterScope.Constant); /// /// Construct input model property /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static InputModelProperty Property( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isDiscriminator = false, bool isHttpMetadata = false, bool isApiVersion = false, InputConstant? defaultValue = null, string? wireName = null, string? summary = null, string? serializedName = null, string? doc = null) { return new InputModelProperty( name: name, summary: summary, doc: doc ?? $"Description for {name}", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, defaultValue: defaultValue, isHttpMetadata: isHttpMetadata, access: null, isDiscriminator: isDiscriminator, serializedName: serializedName ?? wireName ?? name.ToVariableName(), serializationOptions: new(json: new(wireName ?? name.ToVariableName()))); } public static InputHeaderParameter HeaderParameter( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isApiVersion = false, bool isContentType = false, string? summary = null, string? doc = null, string? collectionFormat = null, string? serializedName = null, InputConstant? defaultValue = null, InputParameterScope scope = InputParameterScope.Method) { return new InputHeaderParameter( name: name, summary: summary, doc: doc ?? $"{name} description", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, isContentType: isContentType, access: null, defaultValue: defaultValue, collectionFormat: collectionFormat, scope: scope, arraySerializationDelimiter: null, serializedName: serializedName ?? name); } public static InputQueryParameter QueryParameter( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isApiVersion = false, InputConstant? defaultValue = null, string? summary = null, string? doc = null, string? collectionFormat = null, string? serializedName = null, bool explode = false, InputParameterScope scope = InputParameterScope.Method, string? delimiter = null) { return new InputQueryParameter( name: name, summary: summary, doc: doc ?? $"{name} description", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, defaultValue: defaultValue, scope: scope, arraySerializationDelimiter: delimiter, access: null, serializedName: serializedName ?? name, collectionFormat: collectionFormat, explode: explode); } public static InputPathParameter PathParameter( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isApiVersion = false, InputConstant? defaultValue = null, string? summary = null, string? doc = null, string? serializedName = null, bool allowReserved = false, bool explode = false, bool skipUrlEncoding = false, string? serverUrlTemplate = null, InputParameterScope scope = InputParameterScope.Method) { return new InputPathParameter( name: name, summary: summary, doc: doc ?? $"{name} description", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, explode: explode, defaultValue: defaultValue, scope: scope, skipUrlEncoding: skipUrlEncoding, serverUrlTemplate: serverUrlTemplate, access: null, serializedName: serializedName ?? name, allowReserved: allowReserved); } public static InputEndpointParameter EndpointParameter( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isApiVersion = false, InputConstant? defaultValue = null, string? summary = null, string? doc = null, string? serializedName = null, bool skipUrlEncoding = false, bool isEndpoint = true, string? serverUrlTemplate = null, InputParameterScope scope = InputParameterScope.Client) { return new InputEndpointParameter( name: name, summary: summary, doc: doc ?? $"{name} description", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, defaultValue: defaultValue, scope: scope, skipUrlEncoding: skipUrlEncoding, serverUrlTemplate: serverUrlTemplate, isEndpoint: isEndpoint, access: null, serializedName: serializedName ?? name); } public static InputBodyParameter BodyParameter( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isApiVersion = false, InputConstant? defaultValue = null, string? summary = null, string? doc = null, string? serializedName = null, string[]? contentTypes = null, string? defaultContentType = null, InputParameterScope scope = InputParameterScope.Method) { return new InputBodyParameter( name: name, summary: summary, doc: doc ?? $"{name} description", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, defaultValue: defaultValue, defaultContentType: defaultContentType ?? "application/json", contentTypes: contentTypes ?? ["application/json"], scope: scope, access: null, serializedName: serializedName ?? name); } public static InputMethodParameter MethodParameter( string name, InputType type, bool isRequired = false, bool isReadOnly = false, bool isApiVersion = false, InputConstant? defaultValue = null, string? summary = null, string? doc = null, string? serializedName = null, InputRequestLocation location = InputRequestLocation.Body, InputParameterScope scope = InputParameterScope.Method) { return new InputMethodParameter( name: name, summary: summary, doc: doc ?? $"{name} description", type: type, isRequired: isRequired, isReadOnly: isReadOnly, isApiVersion: isApiVersion, defaultValue: defaultValue, scope: scope, access: null, location: location, serializedName: serializedName ?? name); } /// /// Construct input model type /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static InputModelType Model( string name, string clientNamespace = "Samples.Models", string access = "public", InputModelTypeUsage usage = InputModelTypeUsage.Output | InputModelTypeUsage.Input | InputModelTypeUsage.Json, IEnumerable? properties = null, InputModelType? baseModel = null, bool modelAsStruct = false, string? discriminatedKind = null, InputType? additionalProperties = null, IDictionary? discriminatedModels = null, IEnumerable? derivedModels = null, IReadOnlyList? decorators = null, bool isDynamicModel = false) { IEnumerable propertiesList = properties ?? [Property("StringProperty", InputPrimitiveType.String)]; var model = new InputModelType( name, clientNamespace, name, access, null, null, $"{name} description", usage, [.. propertiesList], baseModel, derivedModels is null ? [] : [.. derivedModels], discriminatedKind, propertiesList.FirstOrDefault(p => p.IsDiscriminator), discriminatedModels is null ? new Dictionary() : discriminatedModels.AsReadOnly(), additionalProperties, modelAsStruct, new(), isDynamicModel); if (decorators is not null) { var decoratorProperty = typeof(InputModelType).GetProperty(nameof(InputModelType.Decorators)); var setDecoratorMethod = decoratorProperty?.GetSetMethod(true); setDecoratorMethod!.Invoke(model, [decorators]); } return model; } /// /// Construct basic service method /// /// /// /// /// /// /// /// /// public static InputBasicServiceMethod BasicServiceMethod( string name, InputOperation operation, string access = "public", IReadOnlyList? parameters = null, InputServiceMethodResponse? response = null, InputServiceMethodResponse? exception = null, string? crossLanguageDefinitionId = null) { return new InputBasicServiceMethod( name, access, [], null, null, operation, parameters ?? [], response ?? ServiceMethodResponse(null, null), exception, false, true, true, crossLanguageDefinitionId ?? string.Empty); } /// /// Construct service method response /// /// /// /// public static InputServiceMethodResponse ServiceMethodResponse(InputType? type, IReadOnlyList? resultSegments) { return new InputServiceMethodResponse(type, resultSegments); } /// /// Construct paging service method /// /// /// /// /// /// /// /// /// public static InputPagingServiceMethod PagingServiceMethod( string name, InputOperation operation, string access = "public", IReadOnlyList? parameters = null, InputServiceMethodResponse? response = null, InputServiceMethodResponse? exception = null, InputPagingServiceMetadata? pagingMetadata = null) { return new InputPagingServiceMethod( name, access, [], null, null, operation, parameters ?? [], response ?? ServiceMethodResponse(null, null), exception, false, true, true, string.Empty, pagingMetadata ?? PagingMetadata([], null, null)); } /// /// Construct paging metadata /// /// /// /// /// public static InputPagingServiceMetadata PagingMetadata(IReadOnlyList itemPropertySegments, InputNextLink? nextLink, InputContinuationToken? continuationToken) { return new InputPagingServiceMetadata(itemPropertySegments, nextLink, continuationToken); } /// /// Construct paging service method /// /// /// /// /// /// /// /// /// public static InputLongRunningServiceMethod LongRunningServiceMethod( string name, InputOperation operation, string access = "public", IReadOnlyList? parameters = null, InputServiceMethodResponse? response = null, InputServiceMethodResponse? exception = null, InputLongRunningServiceMetadata? longRunningServiceMetadata = null) { return new InputLongRunningServiceMethod( name, access, [], null, null, operation, parameters ?? [], response ?? ServiceMethodResponse(null, null), exception, false, true, true, string.Empty, longRunningServiceMetadata ?? LongRunningServiceMetadata(1, OperationResponse(), null)); } /// /// Construct paging metadata /// /// /// /// /// public static InputLongRunningServiceMetadata LongRunningServiceMetadata(int finalState, InputOperationResponse finalResponse, string? resultPath) { return new InputLongRunningServiceMetadata(finalState, finalResponse, resultPath); } /// /// Construct input operation /// /// /// /// /// /// /// /// /// public static InputOperation Operation( string name, string access = "public", IEnumerable? parameters = null, IEnumerable? responses = null, IEnumerable? requestMediaTypes = null, string? path = null, IReadOnlyList? decorators = null, string? ns = null) { var operation = new InputOperation( name, null, "", $"{name} description", null, access, parameters is null ? [] : [.. parameters], responses is null ? [OperationResponse()] : [.. responses], "GET", string.Empty, path ?? string.Empty, null, requestMediaTypes is null ? null : [.. requestMediaTypes], false, true, true, name, ns); if (decorators is not null) { var decoratorProperty = typeof(InputOperation).GetProperty(nameof(InputOperation.Decorators)); var setDecoratorMethod = decoratorProperty?.GetSetMethod(true); setDecoratorMethod!.Invoke(operation, [decorators]); } return operation; } /// /// Construct input operation response /// /// /// /// public static InputOperationResponse OperationResponse(IEnumerable? statusCodes = null, InputType? bodytype = null) { return new InputOperationResponse( statusCodes is null ? [200] : [.. statusCodes], bodytype, [], false, ["application/json"]); } private static readonly Dictionary> _childClientsCache = new(); /// /// Construct input client /// /// /// /// /// /// /// /// /// /// public static InputClient Client(string name, string clientNamespace = "Samples", string? doc = null, IEnumerable? methods = null, IEnumerable? parameters = null, InputClient? parent = null, IReadOnlyList? decorators = null, string? crossLanguageDefinitionId = null, bool? isMultiServiceClient = false) { // when this client has parent, we add the constructed client into the `children` list of the parent var clientChildren = new List(); var client = new InputClient( name, clientNamespace, crossLanguageDefinitionId ?? $"{clientNamespace}.{name}", string.Empty, doc ?? $"{name} description", isMultiServiceClient ?? false, methods is null ? [] : [.. methods], parameters is null ? [] : [.. parameters], parent, clientChildren, [] ); _childClientsCache[client] = clientChildren; // when we have a parent, we need to find the children list of this parent client and update accordingly. if (parent != null && _childClientsCache.TryGetValue(parent, out var children)) { children.Add(client); } if (decorators is not null) { var decoratorProperty = typeof(InputClient).GetProperty(nameof(InputClient.Decorators)); var setDecoratorMethod = decoratorProperty?.GetSetMethod(true); setDecoratorMethod!.Invoke(client, [decorators]); } return client; } public static InputPagingServiceMetadata ContinuationTokenPagingMetadata(InputParameter parameter, string itemPropertyName, string continuationTokenName, InputResponseLocation continuationTokenLocation) { return new InputPagingServiceMetadata( [itemPropertyName], null, continuationToken: new InputContinuationToken(parameter, [continuationTokenName], continuationTokenLocation)); } public static InputType Array(InputType elementType) { return new InputArrayType("list", "list", elementType); } public static InputPagingServiceMetadata NextLinkPagingMetadata(string itemPropertyName, string nextLinkName, InputResponseLocation nextLinkLocation, IReadOnlyList? reinjectedParameters = null) { return PagingMetadata( [itemPropertyName], new InputNextLink(null, [nextLinkName], nextLinkLocation, reinjectedParameters), null); } public static InputEnumType StringEnum( string name, IEnumerable<(string Name, string Value)> values, string access = "public", InputModelTypeUsage usage = InputModelTypeUsage.Input | InputModelTypeUsage.Output, bool isExtensible = false, string clientNamespace = "Sample.Models") { var enumValues = new List(); var enumType = Enum( name, InputPrimitiveType.String, enumValues, access: access, usage: usage, isExtensible: isExtensible, clientNamespace: clientNamespace); foreach (var (valueName, value) in values) { enumValues.Add(EnumMember.String(valueName, value, enumType)); } return enumType; } private static InputEnumType Enum( string name, InputPrimitiveType underlyingType, IReadOnlyList values, string access = "public", InputModelTypeUsage usage = InputModelTypeUsage.Output | InputModelTypeUsage.Input, bool isExtensible = false, string clientNamespace = "Sample.Models") => new InputEnumType( name, clientNamespace, name, access, null, "", $"{name} description", usage, underlyingType, values, isExtensible); } }