-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtest-interfaces.ts
More file actions
170 lines (134 loc) · 5.31 KB
/
test-interfaces.ts
File metadata and controls
170 lines (134 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* Test file to verify capability contract interfaces
*
* This file demonstrates how plugins can implement the IHttpServer
* and IDataEngine interfaces without depending on concrete implementations.
*/
import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';
/**
* Example: Mock HTTP Server Plugin
*
* Shows how a plugin can implement the IHttpServer interface
* without depending on Express, Fastify, or any specific framework.
*/
class MockHttpServer implements IHttpServer {
private routes: Map<string, { method: string; handler: RouteHandler }> = new Map();
get(path: string, handler: RouteHandler): void {
this.routes.set(`GET:${path}`, { method: 'GET', handler });
console.log(`✅ Registered GET ${path}`);
}
post(path: string, handler: RouteHandler): void {
this.routes.set(`POST:${path}`, { method: 'POST', handler });
console.log(`✅ Registered POST ${path}`);
}
put(path: string, handler: RouteHandler): void {
this.routes.set(`PUT:${path}`, { method: 'PUT', handler });
console.log(`✅ Registered PUT ${path}`);
}
delete(path: string, handler: RouteHandler): void {
this.routes.set(`DELETE:${path}`, { method: 'DELETE', handler });
console.log(`✅ Registered DELETE ${path}`);
}
patch(path: string, handler: RouteHandler): void {
this.routes.set(`PATCH:${path}`, { method: 'PATCH', handler });
console.log(`✅ Registered PATCH ${path}`);
}
use(path: string | Middleware, handler?: Middleware): void {
console.log(`✅ Registered middleware`);
}
async listen(port: number): Promise<void> {
console.log(`✅ Mock HTTP server listening on port ${port}`);
}
async close(): Promise<void> {
console.log(`✅ Mock HTTP server closed`);
}
}
/**
* Example: Mock Data Engine Plugin
*
* Shows how a plugin can implement the IDataEngine interface
* without depending on ObjectQL, Prisma, or any specific database.
*/
class MockDataEngine implements IDataEngine {
private store: Map<string, Map<string, any>> = new Map();
private idCounter = 0;
async insert(objectName: string, data: any): Promise<any> {
if (!this.store.has(objectName)) {
this.store.set(objectName, new Map());
}
const id = `${objectName}_${++this.idCounter}`;
const record = { id, ...data };
this.store.get(objectName)!.set(id, record);
console.log(`✅ Inserted into ${objectName}:`, record);
return record;
}
async find(objectName: string, query?: DataEngineQueryOptions): Promise<any[]> {
const objectStore = this.store.get(objectName);
if (!objectStore) {
return [];
}
const results = Array.from(objectStore.values());
console.log(`✅ Found ${results.length} records in ${objectName}`);
return results;
}
async update(objectName: string, id: any, data: any): Promise<any> {
const objectStore = this.store.get(objectName);
if (!objectStore || !objectStore.has(id)) {
throw new Error(`Record ${id} not found in ${objectName}`);
}
const existing = objectStore.get(id);
const updated = { ...existing, ...data };
objectStore.set(id, updated);
console.log(`✅ Updated ${objectName}/${id}:`, updated);
return updated;
}
async delete(objectName: string, id: any): Promise<boolean> {
const objectStore = this.store.get(objectName);
if (!objectStore) {
return false;
}
const deleted = objectStore.delete(id);
console.log(`✅ Deleted ${objectName}/${id}: ${deleted}`);
return deleted;
}
}
/**
* Test the interfaces
*/
async function testInterfaces() {
console.log('\n=== Testing IHttpServer Interface ===\n');
const httpServer: IHttpServer = new MockHttpServer();
// Register routes using the interface
httpServer.get('/api/users', async (req, res) => {
res.json({ users: [] });
});
httpServer.post('/api/users', async (req, res) => {
res.status(201).json({ id: 1, ...req.body });
});
await httpServer.listen(3000);
console.log('\n=== Testing IDataEngine Interface ===\n');
const dataEngine: IDataEngine = new MockDataEngine();
// Use the data engine interface
const user1 = await dataEngine.insert('user', {
name: 'John Doe',
email: 'john@example.com'
});
const user2 = await dataEngine.insert('user', {
name: 'Jane Smith',
email: 'jane@example.com'
});
const users = await dataEngine.find('user');
console.log(`Found ${users.length} users after inserts`);
const updatedUser = await dataEngine.update('user', user1.id, {
name: 'John Updated'
});
console.log(`Updated user:`, updatedUser);
const deleted = await dataEngine.delete('user', user2.id);
console.log(`Delete result: ${deleted}`);
console.log('\n✅ All interface tests passed!\n');
if (httpServer.close) {
await httpServer.close();
}
}
// Run tests
testInterfaces().catch(console.error);