Highly ambitious ATProtocol AppView service and sdks
at fix-postgres 177 lines 5.4 kB view raw
1import { assertEquals, assertStringIncludes } from "jsr:@std/assert"; 2import { generateTypeScript } from "../src/mod.ts"; 3import type { Lexicon } from "../src/mod.ts"; 4 5Deno.test("generateTypeScript - full integration test", async () => { 6 const lexicons: Lexicon[] = [ 7 { 8 id: "com.example.post", 9 definitions: { 10 main: { 11 type: "record", 12 record: { 13 type: "record", 14 properties: { 15 text: { type: "string" }, 16 createdAt: { type: "string" }, 17 likes: { type: "integer" }, 18 tags: { 19 type: "array", 20 items: { type: "string" }, 21 }, 22 }, 23 required: ["text", "createdAt"], 24 }, 25 }, 26 }, 27 }, 28 { 29 id: "com.example.user", 30 definitions: { 31 main: { 32 type: "record", 33 record: { 34 type: "record", 35 properties: { 36 handle: { type: "string" }, 37 displayName: { type: "string" }, 38 }, 39 required: ["handle"], 40 }, 41 }, 42 }, 43 }, 44 { 45 id: "network.slices.slice", 46 definitions: { 47 main: { 48 type: "record", 49 record: { 50 type: "record", 51 properties: { 52 name: { type: "string" }, 53 }, 54 required: ["name"], 55 }, 56 }, 57 }, 58 }, 59 ]; 60 61 const result = await generateTypeScript(lexicons, { 62 sliceUri: "at://did:example/com.example.slice/abc123", 63 }); 64 65 // Should include header comment with usage example 66 assertStringIncludes(result, "Generated TypeScript client for AT Protocol records"); 67 assertStringIncludes(result, "Lexicons: 3"); 68 assertStringIncludes(result, "at://did:example/com.example.slice/abc123"); 69 70 // Should include imports 71 assertStringIncludes(result, 'SlicesClient'); 72 assertStringIncludes(result, 'OAuthClient'); 73 74 // Should include record interfaces 75 assertStringIncludes(result, "export interface ComExamplePost"); 76 assertStringIncludes(result, "export interface ComExampleUser"); 77 assertStringIncludes(result, "text: string;"); 78 assertStringIncludes(result, "handle: string;"); 79 assertStringIncludes(result, "displayName?: string;"); 80 81 // Should include sort fields types 82 assertStringIncludes(result, "export type ComExamplePostSortFields"); 83 assertStringIncludes(result, "export type ComExampleUserSortFields"); 84 85 // Should include client class 86 assertStringIncludes(result, "export class AtProtoClient extends SlicesClient"); 87 assertStringIncludes(result, "readonly com: ComClient;"); 88 89 // Should include CRUD methods 90 assertStringIncludes(result, "async getRecords("); 91 assertStringIncludes(result, "async createRecord("); 92 93 // Should include standard client methods for all lexicons 94 95 // Code should be formatted (no obvious formatting issues) 96 assertEquals(result.includes(" ;"), false); // Double spaces before semicolons 97 assertEquals(result.includes("\t\t\t"), false); // Triple tabs 98}); 99 100Deno.test("generateTypeScript - generates client for standard lexicons", async () => { 101 const lexicons: Lexicon[] = [ 102 { 103 id: "app.bsky.feed.post", 104 definitions: { 105 main: { 106 type: "record", 107 record: { 108 type: "record", 109 properties: { 110 text: { type: "string" }, 111 }, 112 }, 113 }, 114 }, 115 }, 116 ]; 117 118 const result = await generateTypeScript(lexicons, { 119 sliceUri: "at://test/slice", 120 }); 121 122 // Should include basic functionality 123 assertStringIncludes(result, "export interface AppBskyFeedPost"); 124 assertStringIncludes(result, "export class AtProtoClient"); 125 assertStringIncludes(result, "async getRecords("); 126 assertStringIncludes(result, "text?: string;"); 127 128 // Should include imports 129 assertStringIncludes(result, 'SlicesClient'); 130 assertStringIncludes(result, 'OAuthClient'); 131}); 132 133Deno.test("generateTypeScript - handles empty lexicons", async () => { 134 const result = await generateTypeScript([], { 135 sliceUri: "at://test/slice", 136 }); 137 138 // Should include basic structure even with no lexicons 139 assertStringIncludes(result, "Generated TypeScript client"); 140 assertStringIncludes(result, "Lexicons: 0"); 141 assertStringIncludes(result, 'SlicesClient'); 142 143 // Should include imports even with no lexicons 144 assertStringIncludes(result, "@slices/client"); 145 146 // Should not create any client class (no records to work with) 147 assertEquals(result.includes("export class AtProtoClient"), false); 148}); 149 150Deno.test("generateTypeScript - creates correct usage example", async () => { 151 const lexicons: Lexicon[] = [ 152 { 153 id: "social.app.post", 154 definitions: { 155 main: { 156 type: "record", 157 record: { 158 type: "record", 159 properties: { 160 message: { type: "string" }, 161 }, 162 }, 163 }, 164 }, 165 }, 166 ]; 167 168 const result = await generateTypeScript(lexicons, { 169 sliceUri: "at://did:example/slice/123", 170 }); 171 172 // Should create usage example with the first non-network.slices lexicon 173 assertStringIncludes(result, "client.social.app.post.getRecords()"); 174 assertStringIncludes(result, "at://did:example/slice/123"); 175 assertStringIncludes(result, "social.app.post"); 176 assertStringIncludes(result, "getRecords()"); 177});