1[ 2 { 3 "input": "z=b&a=b&z=a&a=a", 4 "output": [["a", "b"], ["a", "a"], ["z", "b"], ["z", "a"]] 5 }, 6 { 7 "input": "\uFFFD=x&\uFFFC&\uFFFD=a", 8 "output": [["\uFFFC", ""], ["\uFFFD", "x"], ["\uFFFD", "a"]] 9 }, 10 { 11 "input": "ffi&", // > code point, but < code unit because two code units 12 "output": [["", ""], ["ffi", ""]] 13 }, 14 { 15 "input": "é&e\uFFFD&e\u0301", 16 "output": [["e\u0301", ""], ["e\uFFFD", ""], ["é", ""]] 17 }, 18 { 19 "input": "z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g", 20 "output": [["a", "a"], ["a", "b"], ["a", "c"], ["a", "d"], ["a", "e"], ["a", "f"], ["a", "g"], ["z", "z"], ["z", "y"], ["z", "x"], ["z", "w"], ["z", "v"], ["z", "u"], ["z", "t"]] 21 }, 22 { 23 "input": "bbb&bb&aaa&aa=x&aa=y", 24 "output": [["aa", "x"], ["aa", "y"], ["aaa", ""], ["bb", ""], ["bbb", ""]] 25 }, 26 { 27 "input": "z=z&=f&=t&=x", 28 "output": [["", "f"], ["", "t"], ["", "x"], ["z", "z"]] 29 }, 30 { 31 "input": "a&a", 32 "output": [["a", ""], ["a", ""]] 33 } 34].forEach((val) => { 35 test(() => { 36 let params = new URLSearchParams(val.input), 37 i = 0 38 params.sort() 39 for(let param of params) { 40 assert_array_equals(param, val.output[i]) 41 i++ 42 } 43 }, "Parse and sort: " + val.input) 44 45 test(() => { 46 let url = new URL("?" + val.input, "https://example/") 47 url.searchParams.sort() 48 let params = new URLSearchParams(url.search), 49 i = 0 50 for(let param of params) { 51 assert_array_equals(param, val.output[i]) 52 i++ 53 } 54 }, "URL parse and sort: " + val.input) 55}) 56 57test(function() { 58 const url = new URL("http://example.com/?") 59 url.searchParams.sort() 60 assert_equals(url.href, "http://example.com/") 61 assert_equals(url.search, "") 62}, "Sorting non-existent params removes ? from URL") 63