import { assertEquals, assertStringIncludes } from "jsr:@std/assert"; import { generateTypeScript } from "../src/mod.ts"; import type { Lexicon } from "../src/mod.ts"; Deno.test("generateTypeScript - full integration test", async () => { const lexicons: Lexicon[] = [ { id: "com.example.post", definitions: { main: { type: "record", record: { type: "record", properties: { text: { type: "string" }, createdAt: { type: "string" }, likes: { type: "integer" }, tags: { type: "array", items: { type: "string" }, }, }, required: ["text", "createdAt"], }, }, }, }, { id: "com.example.user", definitions: { main: { type: "record", record: { type: "record", properties: { handle: { type: "string" }, displayName: { type: "string" }, }, required: ["handle"], }, }, }, }, { id: "network.slices.slice", definitions: { main: { type: "record", record: { type: "record", properties: { name: { type: "string" }, }, required: ["name"], }, }, }, }, ]; const result = await generateTypeScript(lexicons, { sliceUri: "at://did:example/com.example.slice/abc123", }); // Should include header comment with usage example assertStringIncludes(result, "Generated TypeScript client for AT Protocol records"); assertStringIncludes(result, "Lexicons: 3"); assertStringIncludes(result, "at://did:example/com.example.slice/abc123"); // Should include imports assertStringIncludes(result, 'SlicesClient'); assertStringIncludes(result, 'OAuthClient'); // Should include record interfaces assertStringIncludes(result, "export interface ComExamplePost"); assertStringIncludes(result, "export interface ComExampleUser"); assertStringIncludes(result, "text: string;"); assertStringIncludes(result, "handle: string;"); assertStringIncludes(result, "displayName?: string;"); // Should include sort fields types assertStringIncludes(result, "export type ComExamplePostSortFields"); assertStringIncludes(result, "export type ComExampleUserSortFields"); // Should include client class assertStringIncludes(result, "export class AtProtoClient extends SlicesClient"); assertStringIncludes(result, "readonly com: ComClient;"); // Should include CRUD methods assertStringIncludes(result, "async getRecords("); assertStringIncludes(result, "async createRecord("); // Should include standard client methods for all lexicons // Code should be formatted (no obvious formatting issues) assertEquals(result.includes(" ;"), false); // Double spaces before semicolons assertEquals(result.includes("\t\t\t"), false); // Triple tabs }); Deno.test("generateTypeScript - generates client for standard lexicons", async () => { const lexicons: Lexicon[] = [ { id: "app.bsky.feed.post", definitions: { main: { type: "record", record: { type: "record", properties: { text: { type: "string" }, }, }, }, }, }, ]; const result = await generateTypeScript(lexicons, { sliceUri: "at://test/slice", }); // Should include basic functionality assertStringIncludes(result, "export interface AppBskyFeedPost"); assertStringIncludes(result, "export class AtProtoClient"); assertStringIncludes(result, "async getRecords("); assertStringIncludes(result, "text?: string;"); // Should include imports assertStringIncludes(result, 'SlicesClient'); assertStringIncludes(result, 'OAuthClient'); }); Deno.test("generateTypeScript - handles empty lexicons", async () => { const result = await generateTypeScript([], { sliceUri: "at://test/slice", }); // Should include basic structure even with no lexicons assertStringIncludes(result, "Generated TypeScript client"); assertStringIncludes(result, "Lexicons: 0"); assertStringIncludes(result, 'SlicesClient'); // Should include imports even with no lexicons assertStringIncludes(result, "@slices/client"); // Should not create any client class (no records to work with) assertEquals(result.includes("export class AtProtoClient"), false); }); Deno.test("generateTypeScript - creates correct usage example", async () => { const lexicons: Lexicon[] = [ { id: "social.app.post", definitions: { main: { type: "record", record: { type: "record", properties: { message: { type: "string" }, }, }, }, }, }, ]; const result = await generateTypeScript(lexicons, { sliceUri: "at://did:example/slice/123", }); // Should create usage example with the first non-network.slices lexicon assertStringIncludes(result, "client.social.app.post.getRecords()"); assertStringIncludes(result, "at://did:example/slice/123"); assertStringIncludes(result, "social.app.post"); assertStringIncludes(result, "getRecords()"); });