blob: 72c1d3c182cc865d0bbd0b7ba390626b2583d264 [file] [log] [blame]
/*
* Copyright (C) 2015 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.okhttp;
import com.squareup.okhttp.WebPlatformTestRun.SubtestResult;
import com.squareup.okhttp.internal.Util;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import okio.BufferedSource;
import okio.Okio;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/** Runs the web platform URL tests against Java URL models. */
@RunWith(Parameterized.class)
public final class WebPlatformUrlTest {
@Parameterized.Parameters(name = "{0}")
public static List<Object[]> parameters() {
try {
List<WebPlatformUrlTestData> tests = loadTests();
// The web platform tests are run in both HTML and XHTML variants. Major browsers pass more
// tests in HTML mode, so that's what we'll attempt to match.
String testName = "/url/a-element.html";
WebPlatformTestRun firefoxTestRun
= loadTestRun("/web-platform-test-results-url-firefox-37.0.json");
WebPlatformTestRun chromeTestRun
= loadTestRun("/web-platform-test-results-url-chrome-42.0.json");
WebPlatformTestRun safariTestRun
= loadTestRun("/web-platform-test-results-url-safari-7.1.json");
List<Object[]> result = new ArrayList<>();
for (WebPlatformUrlTestData urlTestData : tests) {
String subtestName = urlTestData.toString();
SubtestResult firefoxResult = firefoxTestRun.get(testName, subtestName);
SubtestResult chromeResult = chromeTestRun.get(testName, subtestName);
SubtestResult safariResult = safariTestRun.get(testName, subtestName);
result.add(new Object[] { urlTestData, firefoxResult, chromeResult, safariResult });
}
return result;
} catch (IOException e) {
throw new AssertionError();
}
}
@Parameter(0)
public WebPlatformUrlTestData testData;
@Parameter(1)
public SubtestResult firefoxResult;
@Parameter(2)
public SubtestResult chromeResultResult;
@Parameter(3)
public SubtestResult safariResult;
private static final List<String> JAVA_NET_URL_SCHEMES
= Util.immutableList("file", "ftp", "http", "https", "mailto");
private static final List<String> HTTP_URL_SCHEMES
= Util.immutableList("http", "https");
/** Test how {@link URL} does against the web platform test suite. */
@Ignore // java.net.URL is broken. Not much we can do about that.
@Test public void javaNetUrl() throws Exception {
if (!testData.scheme.isEmpty() && !JAVA_NET_URL_SCHEMES.contains(testData.scheme)) {
System.out.println("Ignoring unsupported scheme " + testData.scheme);
return;
}
try {
testJavaNetUrl();
} catch (AssertionError e) {
if (tolerateFailure()) {
System.out.println("Tolerable failure: " + e.getMessage());
return;
}
throw e;
}
}
private void testJavaNetUrl() {
URL url = null;
String failureMessage = "";
try {
if (testData.base.equals("about:blank")) {
url = new URL(testData.input);
} else {
URL baseUrl = new URL(testData.base);
url = new URL(baseUrl, testData.input);
}
} catch (MalformedURLException e) {
failureMessage = e.getMessage();
}
if (testData.expectParseFailure()) {
assertNull("Expected URL to fail parsing", url);
} else {
assertNotNull("Expected URL to parse successfully, but was " + failureMessage, url);
String effectivePort = url.getPort() != -1 ? Integer.toString(url.getPort()) : "";
String effectiveQuery = url.getQuery() != null ? "?" + url.getQuery() : "";
String effectiveFragment = url.getRef() != null ? "#" + url.getRef() : "";
assertEquals("scheme", testData.scheme, url.getProtocol());
assertEquals("host", testData.host, url.getHost());
assertEquals("port", testData.port, effectivePort);
assertEquals("path", testData.path, url.getPath());
assertEquals("query", testData.query, effectiveQuery);
assertEquals("fragment", testData.fragment, effectiveFragment);
}
}
/** Test how {@link HttpUrl} does against the web platform test suite. */
@Ignore // TODO(jwilson): implement character encoding.
@Test public void httpUrl() throws Exception {
if (!testData.scheme.isEmpty() && !HTTP_URL_SCHEMES.contains(testData.scheme)) {
System.out.println("Ignoring unsupported scheme " + testData.scheme);
return;
}
if (!testData.base.startsWith("https:") && !testData.base.startsWith("http:")) {
System.out.println("Ignoring unsupported base " + testData.base);
return;
}
try {
testHttpUrl();
} catch (AssertionError e) {
if (tolerateFailure()) {
System.out.println("Tolerable failure: " + e.getMessage());
return;
}
throw e;
}
}
private void testHttpUrl() {
HttpUrl url;
if (testData.base.equals("about:blank")) {
url = HttpUrl.parse(testData.input);
} else {
HttpUrl baseUrl = HttpUrl.parse(testData.base);
url = baseUrl.resolve(testData.input);
}
if (testData.expectParseFailure()) {
assertNull("Expected URL to fail parsing", url);
} else {
assertNotNull("Expected URL to parse successfully, but was null", url);
String effectivePort = url.port() != HttpUrl.defaultPort(url.scheme())
? Integer.toString(url.port())
: "";
String effectiveQuery = url.query() != null ? "?" + url.query() : "";
String effectiveFragment = url.fragment() != null ? "#" + url.fragment() : "";
assertEquals("scheme", testData.scheme, url.scheme());
assertEquals("host", testData.host, url.host());
assertEquals("port", testData.port, effectivePort);
assertEquals("path", testData.path, url.path());
assertEquals("query", testData.query, effectiveQuery);
assertEquals("fragment", testData.fragment, effectiveFragment);
}
}
/**
* Returns true if several major browsers also fail this test, in which case the test itself is
* questionable.
*/
private boolean tolerateFailure() {
return !firefoxResult.isPass()
&& !chromeResultResult.isPass()
&& !safariResult.isPass();
}
private static List<WebPlatformUrlTestData> loadTests() throws IOException {
BufferedSource source = Okio.buffer(Okio.source(
WebPlatformUrlTest.class.getResourceAsStream("/web-platform-test-urltestdata.txt")));
return WebPlatformUrlTestData.load(source);
}
private static WebPlatformTestRun loadTestRun(String name) throws IOException {
return WebPlatformTestRun.load(WebPlatformUrlTest.class.getResourceAsStream(name));
}
}