Skip to content

Commit

Permalink
Regex test functionality working
Browse files Browse the repository at this point in the history
  • Loading branch information
fileformat committed Oct 17, 2024
1 parent d61ef4a commit 146955a
Show file tree
Hide file tree
Showing 3 changed files with 268 additions and 11 deletions.
209 changes: 209 additions & 0 deletions src/runTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { type TestInput, type TestOutput } from "./types";

function h(unsafe: string): string {
if (unsafe == null) {
return "";
}

return unsafe
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}

export function runTest(input: TestInput): TestOutput {
if (input.regex == null || input.regex.length == 0) {
return { success: false, message: "No regex to test!" };
}

const options = input.option ? input.option.join("") : undefined;

const html = [];
html.push(
'<table class="table table-bordered table-striped" style="width:auto;">\n'
);

html.push("\t<tr>\n");
html.push("\t\t<td>Regular Expression</td>\n");
html.push("\t\t<td>");
html.push(h(input.regex));
html.push("</td>\n");
html.push("\t</tr>\n");

html.push("\t<tr>\n");
html.push("\t\t<td>Replacement</td>\n");
html.push("\t\t<td>");
html.push(h(input.replacement));
html.push("</td>\n");

html.push("\t<tr>\n");
html.push("\t\t<td>Options</td>\n");
html.push("\t\t<td>");
html.push(options ? h(options) : "<i>(none)</i>");
html.push("</td>\n");
html.push("\t</tr>\n");
html.push("</table>\n");

let compileTest: RegExp;

try {
compileTest = new RegExp(input.regex, options);
} catch (err) {
const message = err instanceof Error ? err.message : `unknown error ${err}`;
return {
success: false,
message: `unable to create RegExp object: ${message}`,
html: html.join(""),
};
}

try {
html.push('<table class="table table-bordered table-striped">\n');

html.push("\t<thead>");
html.push("\t\t<tr>\n");
html.push('\t\t\t<th style="text-align:center;">Test</th>\n');
html.push("\t\t\t<th>Input</th>");
html.push("\t\t\t<th>regex.test()</th>");
html.push("\t\t\t<th>input.replace()</th>");
html.push("\t\t\t<th>input.replaceAll()</th>");
html.push("\t\t\t<th>input.split()[]</th>");
html.push("\t\t\t<th>regex.exec().index</th>");
html.push("\t\t\t<th>regex.exec()[]</th>");
html.push("\t\t\t<th>regex.lastIndex</th>");
html.push("\t\t</tr>\n");
html.push("\t</thead>\n");
html.push("\t<tbody>\n");

var count = 0;

if (input.inputs != null) {
for (var loop = 0; loop < input.inputs.length; loop++) {
var target = input.inputs[loop];

if (target.length == 0) {
continue;
}
html.push("\t\t<tr>\n");

html.push('\t\t\t<td style="text-align:center;">');
html.push(loop + 1);
html.push("</td>\n");

html.push("\t\t\t<td>");
html.push(h(target));
html.push("</td>\n");

html.push("\t\t\t<td>");
html.push(
new RegExp(input.regex, options).test(target) ? "true" : "false"
);
html.push("</td>\n");

html.push("\t\t\t<td>");
html.push(
h(target.replace(new RegExp(input.regex, options), input.replacement))
);
html.push("</td>\n");

html.push("\t\t\t<td>");
try {
html.push(
h(
target.replaceAll(
new RegExp(input.regex, options),
input.replacement
)
)
);
} catch (replaceAllErr) {
const message =
replaceAllErr instanceof Error
? replaceAllErr.message
: `unknown error ${replaceAllErr}`;
html.push(`<i>${message}</i>`);
}
html.push("</td>\n");

html.push("\t\t\t<td>");
var splits = target.split(new RegExp(input.regex, options));
for (var split = 0; split < splits.length; split++) {
html.push("[");
html.push(split);
html.push("]: ");
html.push(splits[split] == null ? "<i>(null)</i>" : h(splits[split]));
html.push("<br/>");
}
html.push("</td>\n");

var regex = new RegExp(input.regex, options);
var result = regex.exec(target);
if (result == null) {
html.push('\t\t\t<td colspan="6"><i>(null)</i></td>\n');
} else {
var first = true;

while (result != null) {
if (first == true) {
first = false;
} else {
html.push("</tr>\n");
html.push('\t\t\t<td colspan="6" style="text-align:right;">');
html.push("regex.exec()");
html.push("</td>\n");
}

html.push("\t\t\t<td>");
html.push(result.index);
html.push("</td>\n");

html.push("\t\t\t<td>");
for (var capture = 0; capture < result.length; capture++) {
html.push("[");
html.push(capture);
html.push("]: ");
html.push(
result[capture] == null ? "<i>(null)</i>" : h(result[capture])
);
html.push("<br/>");
}
html.push("</td>\n");

html.push("\t\t\t<td>");
html.push(regex.lastIndex);
html.push("</td>\n");

result = global ? regex.exec(target) : null;
}
}
html.push("\t\t</tr>\n");
count++;
}
}

if (count == 0) {
html.push("\t\t<tr>\n");
html.push('\t\t<td colspan="8"><i>');
html.push("(no input to test)");
html.push("</i></td>\n");
html.push("\t\t</tr>\n");
}

html.push("\t</tbody>\n");
html.push("</table>\n");
} catch (err) {
const message = err instanceof Error ? err.message : `unknown error ${err}`;
return {
success: false,
message: `unable to run tests: ${message}`,
html: html.join(""),
};
}

return {
success: true,
html: html.join(""),
};
}
54 changes: 43 additions & 11 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { Server } from "bun";
import type { TestInput } from "./types";
import { runTest } from "./runTest";

Bun.serve({
development: process.env.NODE_ENV !== "production",
Expand Down Expand Up @@ -43,7 +45,7 @@ Bun.serve({

return handleJsonp(req, {
success: false,
code: 'ENOTFOUND',
code: "ENOTFOUND",
statusCode: 404,
message: `Not Found: ${pathname}`,
});
Expand All @@ -69,26 +71,56 @@ function handleJsonp(req: Request, data: Object): Response {
});
}

function testJson(req: Request, server: Server): Response {
const body = req.body;
async function testJson(req: Request, server: Server): Promise<Response> {
let testInput: TestInput;

return handleJsonp(req, {
sucess: false,
html: `<div class="alert alert-danger" role="alert">Bun support is not finished yet</div>`,
});
if (req.method === "POST") {
if (req.headers.get("content-type") === "application/json") {
testInput = await req.json();
} else {
const data = await req.formData();
console.log("formData", data);

testInput = {
engine: "bun",
regex: data.get("regex") as string,
replacement: data.get("replacement") as string,
option: data.getAll("option") as string[],
inputs: data.getAll("input") as string[],
};
}
} else {
const searchParams = new URL(req.url).searchParams;
testInput = {
engine: searchParams.get("engine") || "bun",
regex: searchParams.get("regex") || "",
replacement: searchParams.get("replacement") || "",
option: searchParams.getAll("option") as string[],
inputs: searchParams.getAll("input") as string[],
};
console.log("searchParams", searchParams);
}

console.log("testInput", testInput);

const retVal = runTest(testInput);

console.log("testOutput", retVal);

return handleJsonp(req, retVal);
}

function statusJson(req: Request, server: Server): Response {
const retVal = {
success: true,
tech: `Bun v${Bun.version}`,
lastmod: process.env.LASTMOD || '(not set)',
commit: process.env.COMMIT || '(not set)',
lastmod: process.env.LASTMOD || "(not set)",
commit: process.env.COMMIT || "(not set)",
timestamp: new Date().toISOString(),
version: `${Bun.version}`,
revision: `${Bun.revision}`,
'process.arch': process.arch,
'process.platform': process.platform,
"process.arch": process.arch,
"process.platform": process.platform,
};

return handleJsonp(req, retVal);
Expand Down
16 changes: 16 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@


export type TestInput = {
engine: string;
regex: string;
replacement: string;
extras?: string[];
option: string[];
inputs: string[];
};

export type TestOutput = {
success: boolean;
html?: string;
message?: string;
};

0 comments on commit 146955a

Please sign in to comment.