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);
}
}