Skip to content

Commit 146955a

Browse files
committed
Regex test functionality working
1 parent d61ef4a commit 146955a

File tree

3 files changed

+268
-11
lines changed

3 files changed

+268
-11
lines changed

src/runTest.ts

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import { type TestInput, type TestOutput } from "./types";
2+
3+
function h(unsafe: string): string {
4+
if (unsafe == null) {
5+
return "";
6+
}
7+
8+
return unsafe
9+
.replace(/&/g, "&")
10+
.replace(/</g, "&lt;")
11+
.replace(/>/g, "&gt;")
12+
.replace(/"/g, "&quot;")
13+
.replace(/'/g, "&#039;");
14+
}
15+
16+
export function runTest(input: TestInput): TestOutput {
17+
if (input.regex == null || input.regex.length == 0) {
18+
return { success: false, message: "No regex to test!" };
19+
}
20+
21+
const options = input.option ? input.option.join("") : undefined;
22+
23+
const html = [];
24+
html.push(
25+
'<table class="table table-bordered table-striped" style="width:auto;">\n'
26+
);
27+
28+
html.push("\t<tr>\n");
29+
html.push("\t\t<td>Regular Expression</td>\n");
30+
html.push("\t\t<td>");
31+
html.push(h(input.regex));
32+
html.push("</td>\n");
33+
html.push("\t</tr>\n");
34+
35+
html.push("\t<tr>\n");
36+
html.push("\t\t<td>Replacement</td>\n");
37+
html.push("\t\t<td>");
38+
html.push(h(input.replacement));
39+
html.push("</td>\n");
40+
41+
html.push("\t<tr>\n");
42+
html.push("\t\t<td>Options</td>\n");
43+
html.push("\t\t<td>");
44+
html.push(options ? h(options) : "<i>(none)</i>");
45+
html.push("</td>\n");
46+
html.push("\t</tr>\n");
47+
html.push("</table>\n");
48+
49+
let compileTest: RegExp;
50+
51+
try {
52+
compileTest = new RegExp(input.regex, options);
53+
} catch (err) {
54+
const message = err instanceof Error ? err.message : `unknown error ${err}`;
55+
return {
56+
success: false,
57+
message: `unable to create RegExp object: ${message}`,
58+
html: html.join(""),
59+
};
60+
}
61+
62+
try {
63+
html.push('<table class="table table-bordered table-striped">\n');
64+
65+
html.push("\t<thead>");
66+
html.push("\t\t<tr>\n");
67+
html.push('\t\t\t<th style="text-align:center;">Test</th>\n');
68+
html.push("\t\t\t<th>Input</th>");
69+
html.push("\t\t\t<th>regex.test()</th>");
70+
html.push("\t\t\t<th>input.replace()</th>");
71+
html.push("\t\t\t<th>input.replaceAll()</th>");
72+
html.push("\t\t\t<th>input.split()[]</th>");
73+
html.push("\t\t\t<th>regex.exec().index</th>");
74+
html.push("\t\t\t<th>regex.exec()[]</th>");
75+
html.push("\t\t\t<th>regex.lastIndex</th>");
76+
html.push("\t\t</tr>\n");
77+
html.push("\t</thead>\n");
78+
html.push("\t<tbody>\n");
79+
80+
var count = 0;
81+
82+
if (input.inputs != null) {
83+
for (var loop = 0; loop < input.inputs.length; loop++) {
84+
var target = input.inputs[loop];
85+
86+
if (target.length == 0) {
87+
continue;
88+
}
89+
html.push("\t\t<tr>\n");
90+
91+
html.push('\t\t\t<td style="text-align:center;">');
92+
html.push(loop + 1);
93+
html.push("</td>\n");
94+
95+
html.push("\t\t\t<td>");
96+
html.push(h(target));
97+
html.push("</td>\n");
98+
99+
html.push("\t\t\t<td>");
100+
html.push(
101+
new RegExp(input.regex, options).test(target) ? "true" : "false"
102+
);
103+
html.push("</td>\n");
104+
105+
html.push("\t\t\t<td>");
106+
html.push(
107+
h(target.replace(new RegExp(input.regex, options), input.replacement))
108+
);
109+
html.push("</td>\n");
110+
111+
html.push("\t\t\t<td>");
112+
try {
113+
html.push(
114+
h(
115+
target.replaceAll(
116+
new RegExp(input.regex, options),
117+
input.replacement
118+
)
119+
)
120+
);
121+
} catch (replaceAllErr) {
122+
const message =
123+
replaceAllErr instanceof Error
124+
? replaceAllErr.message
125+
: `unknown error ${replaceAllErr}`;
126+
html.push(`<i>${message}</i>`);
127+
}
128+
html.push("</td>\n");
129+
130+
html.push("\t\t\t<td>");
131+
var splits = target.split(new RegExp(input.regex, options));
132+
for (var split = 0; split < splits.length; split++) {
133+
html.push("[");
134+
html.push(split);
135+
html.push("]: ");
136+
html.push(splits[split] == null ? "<i>(null)</i>" : h(splits[split]));
137+
html.push("<br/>");
138+
}
139+
html.push("</td>\n");
140+
141+
var regex = new RegExp(input.regex, options);
142+
var result = regex.exec(target);
143+
if (result == null) {
144+
html.push('\t\t\t<td colspan="6"><i>(null)</i></td>\n');
145+
} else {
146+
var first = true;
147+
148+
while (result != null) {
149+
if (first == true) {
150+
first = false;
151+
} else {
152+
html.push("</tr>\n");
153+
html.push('\t\t\t<td colspan="6" style="text-align:right;">');
154+
html.push("regex.exec()");
155+
html.push("</td>\n");
156+
}
157+
158+
html.push("\t\t\t<td>");
159+
html.push(result.index);
160+
html.push("</td>\n");
161+
162+
html.push("\t\t\t<td>");
163+
for (var capture = 0; capture < result.length; capture++) {
164+
html.push("[");
165+
html.push(capture);
166+
html.push("]: ");
167+
html.push(
168+
result[capture] == null ? "<i>(null)</i>" : h(result[capture])
169+
);
170+
html.push("<br/>");
171+
}
172+
html.push("</td>\n");
173+
174+
html.push("\t\t\t<td>");
175+
html.push(regex.lastIndex);
176+
html.push("</td>\n");
177+
178+
result = global ? regex.exec(target) : null;
179+
}
180+
}
181+
html.push("\t\t</tr>\n");
182+
count++;
183+
}
184+
}
185+
186+
if (count == 0) {
187+
html.push("\t\t<tr>\n");
188+
html.push('\t\t<td colspan="8"><i>');
189+
html.push("(no input to test)");
190+
html.push("</i></td>\n");
191+
html.push("\t\t</tr>\n");
192+
}
193+
194+
html.push("\t</tbody>\n");
195+
html.push("</table>\n");
196+
} catch (err) {
197+
const message = err instanceof Error ? err.message : `unknown error ${err}`;
198+
return {
199+
success: false,
200+
message: `unable to run tests: ${message}`,
201+
html: html.join(""),
202+
};
203+
}
204+
205+
return {
206+
success: true,
207+
html: html.join(""),
208+
};
209+
}

src/server.ts

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import type { Server } from "bun";
2+
import type { TestInput } from "./types";
3+
import { runTest } from "./runTest";
24

35
Bun.serve({
46
development: process.env.NODE_ENV !== "production",
@@ -43,7 +45,7 @@ Bun.serve({
4345

4446
return handleJsonp(req, {
4547
success: false,
46-
code: 'ENOTFOUND',
48+
code: "ENOTFOUND",
4749
statusCode: 404,
4850
message: `Not Found: ${pathname}`,
4951
});
@@ -69,26 +71,56 @@ function handleJsonp(req: Request, data: Object): Response {
6971
});
7072
}
7173

72-
function testJson(req: Request, server: Server): Response {
73-
const body = req.body;
74+
async function testJson(req: Request, server: Server): Promise<Response> {
75+
let testInput: TestInput;
7476

75-
return handleJsonp(req, {
76-
sucess: false,
77-
html: `<div class="alert alert-danger" role="alert">Bun support is not finished yet</div>`,
78-
});
77+
if (req.method === "POST") {
78+
if (req.headers.get("content-type") === "application/json") {
79+
testInput = await req.json();
80+
} else {
81+
const data = await req.formData();
82+
console.log("formData", data);
83+
84+
testInput = {
85+
engine: "bun",
86+
regex: data.get("regex") as string,
87+
replacement: data.get("replacement") as string,
88+
option: data.getAll("option") as string[],
89+
inputs: data.getAll("input") as string[],
90+
};
91+
}
92+
} else {
93+
const searchParams = new URL(req.url).searchParams;
94+
testInput = {
95+
engine: searchParams.get("engine") || "bun",
96+
regex: searchParams.get("regex") || "",
97+
replacement: searchParams.get("replacement") || "",
98+
option: searchParams.getAll("option") as string[],
99+
inputs: searchParams.getAll("input") as string[],
100+
};
101+
console.log("searchParams", searchParams);
102+
}
103+
104+
console.log("testInput", testInput);
105+
106+
const retVal = runTest(testInput);
107+
108+
console.log("testOutput", retVal);
109+
110+
return handleJsonp(req, retVal);
79111
}
80112

81113
function statusJson(req: Request, server: Server): Response {
82114
const retVal = {
83115
success: true,
84116
tech: `Bun v${Bun.version}`,
85-
lastmod: process.env.LASTMOD || '(not set)',
86-
commit: process.env.COMMIT || '(not set)',
117+
lastmod: process.env.LASTMOD || "(not set)",
118+
commit: process.env.COMMIT || "(not set)",
87119
timestamp: new Date().toISOString(),
88120
version: `${Bun.version}`,
89121
revision: `${Bun.revision}`,
90-
'process.arch': process.arch,
91-
'process.platform': process.platform,
122+
"process.arch": process.arch,
123+
"process.platform": process.platform,
92124
};
93125

94126
return handleJsonp(req, retVal);

src/types.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
3+
export type TestInput = {
4+
engine: string;
5+
regex: string;
6+
replacement: string;
7+
extras?: string[];
8+
option: string[];
9+
inputs: string[];
10+
};
11+
12+
export type TestOutput = {
13+
success: boolean;
14+
html?: string;
15+
message?: string;
16+
};

0 commit comments

Comments
 (0)