import { describe, it, expect } 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("{}"); }); }); });