11cb0ef41Sopenharmony_cipromise_test(() => fetch("resources/percent-encoding.json").then(res => res.json()).then(runTests), "Loading data…");
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_cifunction runTests(testUnits) {
41cb0ef41Sopenharmony_ci  for (const testUnit of testUnits) {
51cb0ef41Sopenharmony_ci    // Ignore comments
61cb0ef41Sopenharmony_ci    if (typeof testUnit === "string") {
71cb0ef41Sopenharmony_ci      continue;
81cb0ef41Sopenharmony_ci    }
91cb0ef41Sopenharmony_ci    for (const encoding of Object.keys(testUnit.output)) {
101cb0ef41Sopenharmony_ci      async_test(t => {
111cb0ef41Sopenharmony_ci        const frame = document.body.appendChild(document.createElement("iframe"));
121cb0ef41Sopenharmony_ci        t.add_cleanup(() => frame.remove());
131cb0ef41Sopenharmony_ci        frame.onload = t.step_func_done(() => {
141cb0ef41Sopenharmony_ci          const output = frame.contentDocument.querySelector("a");
151cb0ef41Sopenharmony_ci          // Test that the fragment is always UTF-8 encoded
161cb0ef41Sopenharmony_ci          assert_equals(output.hash, `#${testUnit.output["utf-8"]}`, "fragment");
171cb0ef41Sopenharmony_ci          assert_equals(output.search, `?${testUnit.output[encoding]}`, "query");
181cb0ef41Sopenharmony_ci        });
191cb0ef41Sopenharmony_ci        frame.src = `resources/percent-encoding.py?encoding=${encoding}&value=${toBase64(testUnit.input)}`;
201cb0ef41Sopenharmony_ci      }, `Input ${testUnit.input} with encoding ${encoding}`);
211cb0ef41Sopenharmony_ci    }
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci// Use base64 to avoid relying on the URL parser to get UTF-8 percent-encoding correctly. This does
261cb0ef41Sopenharmony_ci// not use btoa directly as that only works with code points in the range U+0000 to U+00FF,
271cb0ef41Sopenharmony_ci// inclusive.
281cb0ef41Sopenharmony_cifunction toBase64(input) {
291cb0ef41Sopenharmony_ci  const bytes = new TextEncoder().encode(input);
301cb0ef41Sopenharmony_ci  const byteString = Array.from(bytes, byte => String.fromCharCode(byte)).join("");
311cb0ef41Sopenharmony_ci  const encoded = self.btoa(byteString);
321cb0ef41Sopenharmony_ci  return encoded;
331cb0ef41Sopenharmony_ci}
34