Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 25 additions & 21 deletions docs/typescript-parity-report.md

Large diffs are not rendered by default.

76 changes: 63 additions & 13 deletions internal/compiler/testdata/corpus/api/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,76 @@
// Consolidated test suite with inline assertions.

import "node:http";

import { Blob } from "node:buffer";

// @api: request.url
// @api: request.method
// @api: request.headers
// @api: request.body
// @api: request.constructor
// @api: request.text
// @api: request.json
// @api: request.arrayBuffer
// @api: request.blob
// @api: request.bytes
// @api: request.formData
// @api: request.clone
// @expect: https://example.com/api
// @expect: POST
// @expect: application/json
// @expect: true
const h = new Headers();
h.set("Content-Type", "application/json");
const req = new Request("https://example.com/api", {
method: "POST",
headers: h,
body: '{"hello":"world"}'
});

console.log(req.url);
console.log(req.method);
console.log(req.headers.get("Content-Type"));
console.log(req.body !== null);
// @expect: cloned: POST, https://example.com/api, hello
// @expect: text: hello
// @expect: json: world
// @expect: arrayBuffer: 5
// @expect: blob: 5
// @expect: bytes: 5
// @expect: fd: admin
// @expect: search: 42
async function testRequest() {
const h = new Headers();
h.set("Content-Type", "application/json");
const req = new Request("https://example.com/api", {
method: "POST",
headers: h,
body: '{"hello":"world"}'
});

console.log(req.url);
console.log(req.method);
console.log(req.headers.get("Content-Type"));
console.log(req.body !== null);

const reqSimple = new Request("https://example.com/api", { method: "POST", body: "hello" });
const cloned = reqSimple.clone();
console.log("cloned: " + cloned.method + ", " + cloned.url + ", " + (await cloned.text()));
console.log("text: " + (await reqSimple.text()));

const jsonReq = new Request("https://example.com/data", { method: "POST", body: '{"key":"world"}' });
const data = await jsonReq.json<{ key: string }>();
console.log("json: " + data.key);

const abReq = new Request("https://example.com/ab", { method: "POST", body: "hello" });
const ab = await abReq.arrayBuffer();
console.log("arrayBuffer: " + ab.byteLength);

const blobReq = new Request("https://example.com/blob", { method: "POST", body: "hello" });
const bl = await blobReq.blob();
console.log("blob: " + bl.size);

const bytesReq = new Request("https://example.com/bytes", { method: "POST", body: "hello" });
const bArr = await bytesReq.bytes();
console.log("bytes: " + bArr.length);

const fd = new FormData();
fd.append("username", "admin");
const fdReq = new Request("https://example.com/login", { method: "POST", body: fd });
const parsedFd = await fdReq.formData();
console.log("fd: " + parsedFd.get("username"));

const sp = new URLSearchParams("id=42");
const spReq = new Request("https://example.com/query", { method: "POST", body: sp });
const parsedSpFd = await spReq.formData();
console.log("search: " + parsedSpFd.get("id"));
}
testRequest();
74 changes: 54 additions & 20 deletions internal/compiler/testdata/corpus/api/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Consolidated test suite with inline assertions.

import "node:http";

import { Blob } from "node:buffer";

// @api: response.status
// @api: response.statusText
Expand All @@ -11,34 +11,68 @@ import "node:http";
// @api: response.url
// @api: response.text
// @api: response.constructor
// @api: response.json
// @api: response.arrayBuffer
// @api: response.blob
// @api: response.bytes
// @api: response.formData
// @api: response.clone
// @api: response.error
// @api: response.redirect
// @expect: 200
// @expect: OK
// @expect: true
// @expect:
// @expect: hello body
// @expect: cloned: 200, hello body
// @expect: json: 123
// @expect: arrayBuffer: 5
// @expect: blob: 5
// @expect: bytes: 5
// @expect: fd: alice
// @expect: err_status: 0
// @expect: redir_status: 302
// @expect: redir_loc: https://example.com/login
// @expect: static_json: 42
async function testResponse() {
const res = new Response("hello body", { status: 200, statusText: "OK" });
console.log(res.status);
console.log(res.statusText);
console.log(res.ok);
console.log(res.url);
const txt = await res.text();
console.log(txt);
}
testResponse();
const cloned = res.clone();
console.log(await res.text());
console.log("cloned: " + cloned.status + ", " + (await cloned.text()));

// @api: response.json
// @expect: json parsed
console.log("json parsed");
const jsonRes = new Response('{"count":123}');
const j = await jsonRes.json<{ count: number }>();
console.log("json: " + j.count);

// @api: response.arrayBuffer
// @expect: arrayBuffer ok
console.log("arrayBuffer ok");
const abRes = new Response("hello");
const ab = await abRes.arrayBuffer();
console.log("arrayBuffer: " + ab.byteLength);

// @api: response.error
// @expect: error ok
console.log("error ok");
const blobRes = new Response("hello", { headers: { "content-type": "text/plain" } });
const bl = await blobRes.blob();
console.log("blob: " + bl.size);

// @api: response.redirect
// @expect: redirect ok
console.log("redirect ok");
// @expect: hello body
const bytesRes = new Response("hello");
const by = await bytesRes.bytes();
console.log("bytes: " + by.length);

const fd = new FormData();
fd.append("name", "alice");
const fdRes = new Response(fd);
const parsedFd = await fdRes.formData();
console.log("fd: " + parsedFd.get("name"));

const errRes = Response.error();
console.log("err_status: " + errRes.status);

const redirRes = Response.redirect("https://example.com/login", 302);
console.log("redir_status: " + redirRes.status);
console.log("redir_loc: " + redirRes.headers.get("location"));

const staticJsonRes = Response.json({ score: 42 });
const sj = await staticJsonRes.json<{ score: number }>();
console.log("static_json: " + sj.score);
}
testResponse();
83 changes: 83 additions & 0 deletions internal/compiler/testdata/corpus/api/urlpattern.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// ScriptGo Corpus: WHATWG URLPattern Standard API
// Consolidated test suite with inline assertions.

import { URLPattern } from "node:url";

// --- 1. Basic Pathname Pattern with Named Parameter ---
// @api: urlpattern.constructor
// @api: urlpattern.pathname
// @api: urlpattern.test
// @api: urlpattern.exec
// @native.expected: /books/:id
// @native.expected: true
// @native.expected: false
// @native.expected: 123
const p1 = new URLPattern({ pathname: "/books/:id" });
console.log(p1.pathname);
console.log(p1.test("https://example.com/books/123"));
console.log(p1.test("https://example.com/authors/123"));

const res1 = p1.exec("https://example.com/books/123");
if (res1 !== null) {
console.log(res1.pathname.groups["id"]);
}

// --- 2. Multiple Named Parameters in Pathname ---
// @native.expected: v2
// @native.expected: 42
const p2 = new URLPattern({ pathname: "/api/:version/users/:userId" });
const res2 = p2.exec("https://api.example.com/api/v2/users/42");
if (res2 !== null) {
console.log(res2.pathname.groups["version"]);
console.log(res2.pathname.groups["userId"]);
}

// --- 3. Wildcard Pattern ---
// @native.expected: css/theme.css
const p3 = new URLPattern({ pathname: "/static/*" });
const res3 = p3.exec("/static/css/theme.css");
if (res3 !== null) {
console.log(res3.pathname.groups["0"]);
}

// --- 4. Relative Pattern with baseURL ---
// @native.expected: https
// @native.expected: example.com
// @native.expected: 99
const p4 = new URLPattern("/items/:itemId", "https://example.com");
console.log(p4.protocol);
console.log(p4.hostname);
const res4 = p4.exec("https://example.com/items/99");
if (res4 !== null) {
console.log(res4.pathname.groups["itemId"]);
}

// --- 5. Search Query Parameter Matching ---
// @native.expected: scriptgo
const p5 = new URLPattern({ pathname: "/search", search: "q=:query" });
const res5 = p5.exec("https://example.com/search?q=scriptgo");
if (res5 !== null) {
console.log(res5.search.groups["query"]);
}

// --- 6. Optional Parameters ---
// @native.expected: with_id: 101
// @native.expected: no_id: true
const p6 = new URLPattern({ pathname: "/posts/:id?" });
const res6a = p6.exec("/posts/101");
if (res6a !== null) {
console.log("with_id: " + res6a.pathname.groups["id"]);
}
const res6b = p6.exec("/posts");
if (res6b !== null) {
console.log("no_id: " + (res6b.pathname.groups["id"] === undefined));
}

// --- 7. Custom Regular Expression Constraint ---
// @native.expected: digits_only: true
// @native.expected: non_digits: false
// @native.expected: true
const p7 = new URLPattern({ pathname: "/orders/:orderId(\\d+)" });
console.log("digits_only: " + p7.test("/orders/12345"));
console.log("non_digits: " + p7.test("/orders/abcde"));
console.log(p7.hasRegExpGroups);
Loading
Loading