mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
237 lines
9.4 KiB
TypeScript
237 lines
9.4 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
|
|
describe("URLSearchParams", () => {
|
|
it("does not crash when calling .toJSON() on a URLSearchParams object with a large number of properties", () => {
|
|
const props = {
|
|
"id": "1296269",
|
|
"node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5",
|
|
"name": "Hello-World",
|
|
"full_name": "octocat/Hello-World",
|
|
"owner": "[object Object]",
|
|
"private": "false",
|
|
"html_url": "https://github.com/octocat/Hello-World",
|
|
"description": "This your first repo!",
|
|
"fork": "false",
|
|
"url": "https://api.github.com/repos/octocat/Hello-World",
|
|
"archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}",
|
|
"assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}",
|
|
"blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}",
|
|
"branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}",
|
|
"collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}",
|
|
"comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}",
|
|
"commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}",
|
|
"compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}",
|
|
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}",
|
|
"contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors",
|
|
"deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments",
|
|
"downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads",
|
|
"events_url": "https://api.github.com/repos/octocat/Hello-World/events",
|
|
"forks_url": "https://api.github.com/repos/octocat/Hello-World/forks",
|
|
"git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}",
|
|
"git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}",
|
|
"git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}",
|
|
"git_url": "git:github.com/octocat/Hello-World.git",
|
|
"issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}",
|
|
"issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}",
|
|
"issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}",
|
|
"keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}",
|
|
"labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}",
|
|
"languages_url": "https://api.github.com/repos/octocat/Hello-World/languages",
|
|
"merges_url": "https://api.github.com/repos/octocat/Hello-World/merges",
|
|
"milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}",
|
|
"notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}",
|
|
"pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}",
|
|
"releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}",
|
|
"ssh_url": "git@github.com:octocat/Hello-World.git",
|
|
"stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers",
|
|
"statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}",
|
|
"subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers",
|
|
"subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription",
|
|
"tags_url": "https://api.github.com/repos/octocat/Hello-World/tags",
|
|
"teams_url": "https://api.github.com/repos/octocat/Hello-World/teams",
|
|
"trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}",
|
|
"clone_url": "https://github.com/octocat/Hello-World.git",
|
|
"mirror_url": "git:git.example.com/octocat/Hello-World",
|
|
"hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks",
|
|
"svn_url": "https://svn.github.com/octocat/Hello-World",
|
|
"homepage": "https://github.com",
|
|
"language": "null",
|
|
"forks_count": "9",
|
|
"stargazers_count": "80",
|
|
"watchers_count": "80",
|
|
"size": "108",
|
|
"default_branch": "master",
|
|
"open_issues_count": "0",
|
|
"is_template": "false",
|
|
"topics": "octocat,atom,electron,api",
|
|
"has_issues": "true",
|
|
"has_projects": "true",
|
|
"has_wiki": "true",
|
|
"has_pages": "false",
|
|
"has_downloads": "true",
|
|
"has_discussions": "false",
|
|
"archived": "false",
|
|
"disabled": "false",
|
|
"visibility": "public",
|
|
"pushed_at": "2011-01-26T19:06:43Z",
|
|
"created_at": "2011-01-26T19:01:12Z",
|
|
"updated_at": "2011-01-26T19:14:43Z",
|
|
"permissions": "[object Object]",
|
|
"security_and_analysis": "[object Object]",
|
|
};
|
|
var params = new URLSearchParams();
|
|
for (const key in props) {
|
|
params.set(key, props[key as keyof typeof props]);
|
|
}
|
|
|
|
// @ts-expect-error
|
|
expect(params.toJSON()).toEqual(props);
|
|
|
|
expect(Array.from(params.keys())).toHaveLength(params.size);
|
|
});
|
|
|
|
describe("non-standard extensions", () => {
|
|
it("should support .length", () => {
|
|
const params = new URLSearchParams();
|
|
params.append("foo", "bar");
|
|
params.append("foo", "boop");
|
|
params.append("bar", "baz");
|
|
// @ts-ignore
|
|
expect(params.length).toBe(3);
|
|
params.delete("foo");
|
|
// @ts-ignore
|
|
expect(params.length).toBe(1);
|
|
params.append("foo", "bar");
|
|
// @ts-ignore
|
|
expect(params.length).toBe(2);
|
|
params.delete("foo");
|
|
params.delete("foo");
|
|
// @ts-ignore
|
|
expect(params.length).toBe(1);
|
|
params.delete("bar");
|
|
// @ts-ignore
|
|
expect(params.length).toBe(0);
|
|
});
|
|
|
|
it("should support .toJSON", () => {
|
|
const params = new URLSearchParams();
|
|
params.append("foo", "bar");
|
|
params.append("foo", "boop");
|
|
params.append("bar", "baz");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
foo: ["bar", "boop"],
|
|
bar: "baz",
|
|
});
|
|
expect(JSON.parse(JSON.stringify(params))).toEqual({
|
|
foo: ["bar", "boop"],
|
|
bar: "baz",
|
|
});
|
|
expect(Bun.inspect(params)).toBe(
|
|
"URLSearchParams {" + "\n" + ' "foo": [ "bar", "boop" ],' + "\n" + ' "bar": "baz",' + "\n" + "}",
|
|
);
|
|
params.delete("foo");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
bar: "baz",
|
|
});
|
|
params.append("foo", "bar");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
foo: "bar",
|
|
bar: "baz",
|
|
});
|
|
params.delete("foo");
|
|
params.delete("foo");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
bar: "baz",
|
|
});
|
|
params.delete("bar");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({});
|
|
|
|
expect(JSON.stringify(params)).toBe("{}");
|
|
});
|
|
|
|
it("should handle numeric string keys in .toJSON", () => {
|
|
const params = new URLSearchParams();
|
|
params.set("39208", "updated");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({ "39208": "updated" });
|
|
});
|
|
|
|
it("should handle various numeric keys in .toJSON", () => {
|
|
const params = new URLSearchParams();
|
|
params.set("0", "zero");
|
|
params.set("100", "hundred");
|
|
params.set("99999", "large");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
"0": "zero",
|
|
"100": "hundred",
|
|
"99999": "large",
|
|
});
|
|
});
|
|
|
|
it("should handle mixed numeric and non-numeric keys in .toJSON", () => {
|
|
const params = new URLSearchParams();
|
|
params.set("name", "John");
|
|
params.set("123", "numeric");
|
|
params.set("age", "30");
|
|
params.set("456", "another");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
"name": "John",
|
|
"123": "numeric",
|
|
"age": "30",
|
|
"456": "another",
|
|
});
|
|
});
|
|
|
|
it("should handle duplicate numeric keys in .toJSON", () => {
|
|
const params = new URLSearchParams();
|
|
params.append("100", "first");
|
|
params.append("100", "second");
|
|
params.append("name", "test");
|
|
// @ts-ignore
|
|
expect(params.toJSON()).toEqual({
|
|
"100": ["first", "second"],
|
|
"name": "test",
|
|
});
|
|
});
|
|
|
|
it("toJSON with extra arguments should not crash", () => {
|
|
const params = new URLSearchParams();
|
|
params.set("39208", "updated");
|
|
// toJSON should ignore extra arguments
|
|
// @ts-ignore - intentionally passing extra args
|
|
const result = params.toJSON({}, URLSearchParams, {}, "updated");
|
|
expect(result).toEqual({ "39208": "updated" });
|
|
});
|
|
});
|
|
});
|
|
|
|
it("size property should be configurable (issue #9251)", () => {
|
|
const descriptor = Object.getOwnPropertyDescriptor(URLSearchParams.prototype, "size");
|
|
expect(descriptor).toBeDefined();
|
|
expect(descriptor!.configurable).toBe(true);
|
|
expect(descriptor!.enumerable).toBe(true);
|
|
});
|
|
|
|
it(".delete second argument", () => {
|
|
const params = new URLSearchParams("a=1&a=2&b=3");
|
|
params.delete("a", 1);
|
|
params.delete("b", undefined);
|
|
expect(params + "").toBe("a=2");
|
|
});
|
|
|
|
it(".has second argument", () => {
|
|
const params = new URLSearchParams("a=1&a=2&b=3");
|
|
expect(params.has("a", 1)).toBe(true);
|
|
expect(params.has("a", 2)).toBe(true);
|
|
expect(params.has("a", 3)).toBe(false);
|
|
expect(params.has("b", 3)).toBe(true);
|
|
expect(params.has("b", 4)).toBe(false);
|
|
});
|