microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
a6b7827fcd2db3bf604d42e235216c8d5b244f13

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/http/test/test-host.ts

107lines · modecode

1import { Diagnostic } from "@typespec/compiler";
2import {
3 BasicTestRunner,
4 createTestHost,
5 createTestWrapper,
6 expectDiagnosticEmpty,
7 TestHost,
8} from "@typespec/compiler/testing";
9import {
10 getAllHttpServices,
11 HttpOperation,
12 HttpOperationParameter,
13 HttpVerb,
14 RouteResolutionOptions,
15} from "../src/index.js";
16import { HttpTestLibrary } from "../src/testing/index.js";
17
18export async function createHttpTestHost(): Promise<TestHost> {
19 return createTestHost({
20 libraries: [HttpTestLibrary],
21 });
22}
23export async function createHttpTestRunner(): Promise<BasicTestRunner> {
24 const host = await createHttpTestHost();
25 return createTestWrapper(host, { autoUsings: ["TypeSpec.Http"] });
26}
27
28export interface RouteDetails {
29 path: string;
30 verb: HttpVerb;
31 params: string[];
32}
33
34export async function getRoutesFor(
35 code: string,
36 routeOptions?: RouteResolutionOptions
37): Promise<RouteDetails[]> {
38 const [routes, diagnostics] = await compileOperations(code, routeOptions);
39 expectDiagnosticEmpty(diagnostics);
40 return routes.map((route) => ({
41 ...route,
42 params: route.params.params
43 .map(({ type, name }) => (type === "path" ? name : undefined))
44 .filter((p) => p !== undefined) as string[],
45 }));
46}
47
48export interface SimpleOperationDetails {
49 verb: HttpVerb;
50 path: string;
51 params: {
52 params: Array<{ name: string; type: HttpOperationParameter["type"] }>;
53 /**
54 * name of explicit `@body` parameter or array of unannotated parameter names that make up the body.
55 */
56 body?: string | string[];
57 };
58}
59
60export async function compileOperations(
61 code: string,
62 routeOptions?: RouteResolutionOptions
63): Promise<[SimpleOperationDetails[], readonly Diagnostic[]]> {
64 const [routes, diagnostics] = await getOperationsWithServiceNamespace(code, routeOptions);
65
66 const details = routes.map((r) => {
67 return {
68 verb: r.verb,
69 path: r.path,
70 params: {
71 params: r.parameters.parameters.map(({ type, name }) => ({ type, name })),
72 body:
73 r.parameters.body?.parameter?.name ??
74 (r.parameters.body?.type?.kind === "Model"
75 ? Array.from(r.parameters.body.type.properties.keys())
76 : undefined),
77 },
78 };
79 });
80
81 return [details, diagnostics];
82}
83
84export async function getOperationsWithServiceNamespace(
85 code: string,
86 routeOptions?: RouteResolutionOptions
87): Promise<[HttpOperation[], readonly Diagnostic[]]> {
88 const runner = await createHttpTestRunner();
89 await runner.compileAndDiagnose(
90 `@service({title: "Test Service"}) namespace TestService;
91 ${code}`,
92 {
93 noEmit: true,
94 }
95 );
96 const [services] = getAllHttpServices(runner.program, routeOptions);
97 return [services[0].operations, runner.program.diagnostics];
98}
99
100export async function getOperations(code: string): Promise<HttpOperation[]> {
101 const runner = await createHttpTestRunner();
102 await runner.compile(code);
103 const [services, diagnostics] = getAllHttpServices(runner.program);
104
105 expectDiagnosticEmpty(diagnostics);
106 return services[0].operations;
107}
108