Thin MongoDB ODM built for Standard Schema
mongodb
zod
deno
1#!/usr/bin/env -S deno run --allow-run --allow-read
2
3/**
4 * Test runner script for Nozzle ORM
5 *
6 * Usage:
7 * deno run --allow-run --allow-read scripts/test.ts [options]
8 *
9 * Options:
10 * --mock Run only mock tests (no MongoDB required)
11 * --real Run integration tests (requires MongoDB)
12 * --all Run all tests (default)
13 * --bdd Use BDD-style output for mock tests
14 * --filter Filter tests by name pattern
15 * --watch Watch for file changes and re-run tests
16 * --help Show this help message
17 */
18
19interface TestOptions {
20 mock?: boolean;
21 real?: boolean;
22 all?: boolean;
23 bdd?: boolean;
24 filter?: string;
25 watch?: boolean;
26 help?: boolean;
27}
28
29function parseArgs(): TestOptions {
30 const args = Deno.args;
31 const options: TestOptions = {};
32
33 for (let i = 0; i < args.length; i++) {
34 const arg = args[i];
35 switch (arg) {
36 case "--mock":
37 options.mock = true;
38 break;
39 case "--real":
40 options.real = true;
41 break;
42 case "--all":
43 options.all = true;
44 break;
45 case "--bdd":
46 options.bdd = true;
47 break;
48 case "--filter":
49 options.filter = args[++i];
50 break;
51 case "--watch":
52 options.watch = true;
53 break;
54 case "--help":
55 options.help = true;
56 break;
57 }
58 }
59
60 // Default to all tests if no specific option is provided
61 if (!options.mock && !options.real && !options.help) {
62 options.all = true;
63 }
64
65 return options;
66}
67
68function showHelp() {
69 console.log(`
70🧪 Nozzle ORM Test Runner
71
72Usage:
73 deno run --allow-run --allow-read scripts/test.ts [options]
74
75Options:
76 --mock Run only mock tests (no MongoDB required)
77 --real Run integration tests (requires MongoDB)
78 --all Run all tests (default)
79 --bdd Use BDD-style output for mock tests
80 --filter Filter tests by name pattern
81 --watch Watch for file changes and re-run tests
82 --help Show this help message
83
84Examples:
85 scripts/test.ts # Run all tests
86 scripts/test.ts --mock # Run only mock tests
87 scripts/test.ts --real # Run only integration tests
88 scripts/test.ts --mock --bdd # Run mock tests with BDD output
89 scripts/test.ts --filter "Insert" # Run tests matching "Insert"
90 scripts/test.ts --watch --mock # Watch and run mock tests
91
92Prerequisites for integration tests:
93 - MongoDB running on localhost:27017
94 - Or update connection string in tests/main_test.ts
95 `);
96}
97
98async function runCommand(cmd: string[]) {
99 const process = new Deno.Command(cmd[0], {
100 args: cmd.slice(1),
101 stdout: "inherit",
102 stderr: "inherit",
103 });
104
105 const { success, code } = await process.output();
106 return { success, code };
107}
108
109async function runTests(options: TestOptions) {
110 const baseCmd = ["deno", "test"];
111 const permissions = [
112 "--allow-net",
113 "--allow-read",
114 "--allow-write",
115 "--allow-env",
116 "--allow-sys",
117 ];
118
119 if (options.help) {
120 showHelp();
121 return;
122 }
123
124 console.log("🚀 Starting Nozzle Tests...\n");
125
126 if (options.mock) {
127 console.log("📋 Running mock tests (no MongoDB required)...");
128 const cmd = [...baseCmd, "tests/mock_test.ts"];
129 if (options.bdd) {
130 cmd.push("--reporter", "pretty");
131 }
132 if (options.filter) {
133 cmd.push("--filter", options.filter);
134 }
135 if (options.watch) {
136 cmd.push("--watch");
137 }
138
139 const result = await runCommand(cmd);
140 if (!result.success) {
141 console.error("❌ Mock tests failed");
142 Deno.exit(result.code);
143 } else {
144 console.log("✅ Mock tests passed!");
145 }
146 }
147
148 if (options.real) {
149 console.log("🗄️ Running integration tests (MongoDB required)...");
150 console.log("⚠️ Make sure MongoDB is running on localhost:27017\n");
151
152 const cmd = [...baseCmd, ...permissions, "tests/main_test.ts"];
153 if (options.filter) {
154 cmd.push("--filter", options.filter);
155 }
156 if (options.watch) {
157 cmd.push("--watch");
158 }
159
160 const result = await runCommand(cmd);
161 if (!result.success) {
162 console.error("❌ Integration tests failed");
163 if (result.code === 1) {
164 console.log("\n💡 Troubleshooting tips:");
165 console.log(
166 " • Ensure MongoDB is running: brew services start mongodb-community",
167 );
168 console.log(
169 " • Or start with Docker: docker run -p 27017:27017 -d mongo",
170 );
171 console.log(" • Check connection at: mongodb://localhost:27017");
172 }
173 Deno.exit(result.code);
174 } else {
175 console.log("✅ Integration tests passed!");
176 }
177 }
178
179 if (options.all) {
180 console.log("🎯 Running all tests...\n");
181
182 // Run mock tests first
183 console.log("1️⃣ Running mock tests...");
184 const mockCmd = [...baseCmd, "tests/mock_test.ts"];
185 if (options.bdd) {
186 mockCmd.push("--reporter", "pretty");
187 }
188 if (options.filter) {
189 mockCmd.push("--filter", options.filter);
190 }
191
192 const mockResult = await runCommand(mockCmd);
193 if (mockResult.success) {
194 console.log("✅ Mock tests passed!\n");
195 } else {
196 console.error("❌ Mock tests failed\n");
197 }
198
199 // Run integration tests
200 console.log("2️⃣ Running integration tests...");
201 console.log("⚠️ Make sure MongoDB is running on localhost:27017\n");
202
203 const integrationCmd = [...baseCmd, ...permissions, "tests/main_test.ts"];
204 if (options.filter) {
205 integrationCmd.push("--filter", options.filter);
206 }
207 if (options.watch) {
208 integrationCmd.push("--watch");
209 }
210
211 const integrationResult = await runCommand(integrationCmd);
212
213 if (mockResult.success && integrationResult.success) {
214 console.log("\n🎉 All tests passed!");
215 } else {
216 console.error("\n💥 Some tests failed!");
217 if (!integrationResult.success) {
218 console.log("\n💡 Integration test troubleshooting:");
219 console.log(
220 " • Ensure MongoDB is running: brew services start mongodb-community",
221 );
222 console.log(
223 " • Or start with Docker: docker run -p 27017:27017 -d mongo",
224 );
225 console.log(" • Check connection at: mongodb://localhost:27017");
226 }
227 Deno.exit(Math.max(mockResult.code, integrationResult.code));
228 }
229 }
230}
231
232if (import.meta.main) {
233 const options = parseArgs();
234 await runTests(options);
235}