blob: b022cdbc194aeab8352eed6758d6042aa7b2a23d [file] [log] [blame]
/*
* Copyright 2010 Google 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.google.gwt.core.ext.linker.impl;
import com.google.gwt.util.tools.Utility;
import com.gargoylesoftware.htmlunit.AlertHandler;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.MockWebConnection;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebClient;
import junit.framework.TestCase;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Tests the JavaScript code in the selection script test using HtmlUnit.
*/
public class SelectionScriptJavaScriptTest extends TestCase {
private static String TEST_MODULE_NAME = "test.Module";
/**
* Return script code that includes the definition of computeScriptBase(),
* most of the variables it needs to run, and a call to the function. It
* assumes that the metaProps variable is already in scope.
*/
private static String loadComputeScriptBase() throws IOException {
StringBuilder code = new StringBuilder();
code.append("var base = \"\", $doc=document;\n");
code.append("__gwt_getMetaProperty = function(name) { "
+ "var value = metaProps[name];"
+ "return (value == null) ? null : value; }");
code.append(Utility.getFileFromClassPath(SelectionScriptLinker.COMPUTE_SCRIPT_BASE_JS));
code.append("computeScriptBase();\n");
return code.toString();
}
/**
* Return script code that includes the definition of processMetas(), all
* variables it needs to run, and a call to the function.
*/
private static String loadProcessMetas() throws IOException {
StringBuilder code = new StringBuilder();
code.append("var metaProps = { }, propertyErrorFunc, onLoadErrorFunc;\n");
code.append(Utility.getFileFromClassPath(SelectionScriptLinker.PROCESS_METAS_JS));
code.append("processMetas();\n");
return code.toString().replaceAll("__MODULE_NAME__", TEST_MODULE_NAME);
}
/**
* Test a meta tag specifying a base for this module
*/
public void testModuleSpecificMetas1() throws IOException {
StringBuilder metas = new StringBuilder();
metas.append("<meta name=\"" + TEST_MODULE_NAME
+ "::gwt:property\" content=\"baseUrl=http://new/base\">\n");
StringBuilder testCode = new StringBuilder();
testCode.append(loadProcessMetas());
testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
List<String> alerts = loadPage(makeHostPage(metas), testCode);
assertEquals(1, alerts.size());
assertEquals("baseUrl=http://new/base", alerts.get(0));
}
/**
* Test a meta tag specifying a base for a different module.
*/
public void testModuleSpecificMetas2() throws IOException {
StringBuilder metas = new StringBuilder();
metas.append("<meta name=\"some.other.module::gwt:property\" content=\"baseUrl=http://new/base\">\n");
StringBuilder testCode = new StringBuilder();
testCode.append(loadProcessMetas());
testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
List<String> alerts = loadPage(makeHostPage(metas), testCode);
assertEquals(1, alerts.size());
assertEquals("baseUrl=undefined", alerts.get(0));
}
/**
* Test that all the meta tags are extracted.
*/
public void testProcessMetas() throws FailingHttpStatusCodeException,
MalformedURLException, IOException {
StringBuilder metas = new StringBuilder();
metas.append("<meta name=\"gwt:property\" content=\"baseUrl=http://new/base\">\n");
metas.append("<meta name=\"gwt:property\" content=\"novalue\">\n");
metas.append("<meta name=\"gwt:onPropertyErrorFn\" content=\"function() { alert('custom prop error called');}\"}>\n");
metas.append("<meta name=\"gwt:onLoadErrorFn\" content=\"function() { alert('custom onLoad error called');}\">\n");
StringBuilder testCode = new StringBuilder();
testCode.append(loadProcessMetas());
testCode.append("alert('baseUrl='+metaProps['baseUrl']);\n");
testCode.append("alert('novalue='+metaProps['novalue']);\n");
testCode.append("alert('absent='+metaProps['absent']);\n");
testCode.append("propertyErrorFunc();\n");
testCode.append("onLoadErrorFunc();\n");
List<String> alerts = loadPage(makeHostPage(metas), testCode);
assertEquals(5, alerts.size());
Iterator<String> alertsIter = alerts.iterator();
assertEquals("baseUrl=http://new/base", alertsIter.next());
assertEquals("novalue=", alertsIter.next());
assertEquals("absent=undefined", alertsIter.next());
assertEquals("custom prop error called", alertsIter.next());
assertEquals("custom onLoad error called", alertsIter.next());
}
/**
* Test the default href
*/
public void testDefault() throws IOException {
StringBuilder testCode = new StringBuilder();
testCode.append("var metaProps = { };\n");
testCode.append("function isBodyLoaded() { return true; }\n");
testCode.append(loadComputeScriptBase());
testCode.append("alert('base='+base);\n");
List<String> alerts = loadPage(makeHostPage(""), testCode);
assertEquals(1, alerts.size());
assertEquals("base=http://foo.test/", alerts.get(0));
}
/**
* Test the script base with no meta properties.
*/
public void testScriptBase() throws IOException {
StringBuilder testCode = new StringBuilder();
testCode.append("var metaProps = { };\n");
testCode.append("function isBodyLoaded() { return false; }\n");
testCode.append(loadComputeScriptBase());
testCode.append("alert('base='+base);\n");
List<String> alerts = loadPage(makeHostPage(""), testCode);
assertEquals(1, alerts.size());
assertEquals("base=http://foo.test/foo/", alerts.get(0));
}
/**
* Test getting the base URL from a meta property with an absolute URL
*/
public void testScriptBaseFromMetas() throws IOException {
StringBuilder testCode = new StringBuilder();
testCode.append("var metaProps = { baseUrl : \"http://static.test/fromMetaTag/\" };\n");
testCode.append(loadComputeScriptBase());
testCode.append("alert('base='+base);\n");
List<String> alerts = loadPage(makeHostPage(""), testCode);
assertEquals(1, alerts.size());
assertEquals("base=http://static.test/fromMetaTag/", alerts.get(0));
}
/**
* Test getting the base URL from a meta property with a relative URL
*/
public void testRelativeScriptBaseFromMetas() throws IOException {
StringBuilder testCode = new StringBuilder();
testCode.append("var metaProps = { baseUrl : \"fromMeta/tag/\" };\n");
testCode.append(loadComputeScriptBase());
testCode.append("alert('base='+base);\n");
List<String> alerts = loadPage(makeHostPage(""), testCode);
assertEquals(1, alerts.size());
assertEquals("base=http://foo.test/fromMeta/tag/", alerts.get(0));
}
/**
* Test the script base logic for an inlined selection script.
*/
public void testScriptBaseForInlined() throws IOException {
StringBuilder hostPage = new StringBuilder();
hostPage.append("<html><head>\n");
hostPage.append("<script lang=\"javascript\"><!--\n");
hostPage.append("var metaProps = { }\n");
hostPage.append(loadComputeScriptBase());
hostPage.append("alert('base='+base);\n");
hostPage.append("--></script>\n");
List<String> alerts = loadPage(hostPage.toString(), "");
assertEquals(1, alerts.size());
assertEquals("base=http://foo.test/", alerts.get(0));
}
/**
* Test getting a the base URL from the HTML base tag
*/
public void testScriptBaseFromBaseTag() throws IOException {
StringBuilder hostPage = new StringBuilder();
hostPage.append("<html><head>\n");
hostPage.append("<base href=\"http://static.test/fromBaseTag/\">\n");
hostPage.append("<script lang=\"javascript\"><!--\n");
hostPage.append("var metaProps = { }\n");
hostPage.append(loadComputeScriptBase());
hostPage.append("alert('base='+base);\n");
hostPage.append("--></script>\n");
List<String> alerts = loadPage(hostPage.toString(), "");
assertEquals(1, alerts.size());
assertEquals("base=http://static.test/fromBaseTag/", alerts.get(0));
}
/**
* Test the script base logic for an inlined selection script.
*/
public void testNocacheJsTag() throws IOException {
StringBuilder hostPage = new StringBuilder();
hostPage.append("<html><head>\n");
hostPage.append("<script lang='javascript' type='application/javascript' ");
hostPage.append("src='from/nocache/__MODULE_NAME__.nocache.js'></script>\n");
hostPage.append("<script lang=\"javascript\"><!--\n");
hostPage.append("var metaProps = { }\n");
hostPage.append(loadComputeScriptBase());
hostPage.append("alert('base='+base);\n");
hostPage.append("--></script>\n");
List<String> alerts = loadPage(hostPage.toString(), "");
assertEquals(1, alerts.size());
assertEquals("base=http://foo.test/from/nocache/", alerts.get(0));
}
/**
* Load a page and return all alerts that it generates.
*/
private List<String> loadPage(String hostPage, CharSequence testScript)
throws FailingHttpStatusCodeException, MalformedURLException, IOException {
WebClient webClient = new WebClient();
// Make a mock web connection that can return the host page and the test
// script
MockWebConnection webConnection = new MockWebConnection();
webConnection.setDefaultResponse(hostPage, "text/html");
webConnection.setResponse(new URL(
"http://foo.test/foo/test.Module.nocache.js"), testScript.toString(),
"application/javascript");
webConnection.setResponse(new URL(
"http://foo.test/from/nocache/__MODULE_NAME__.nocache.js"),
testScript.toString(),
"application/javascript");
webClient.setWebConnection(webConnection);
final List<String> alerts = new ArrayList<String>();
webClient.setAlertHandler(new AlertHandler() {
@Override
public void handleAlert(Page page, String msg) {
alerts.add(msg);
}
});
webClient.getPage("http://foo.test/");
return alerts;
}
private String makeHostPage(CharSequence metas) {
StringBuilder buf = new StringBuilder();
buf.append("<html><head>\n");
buf.append(metas);
buf.append("<script src=\"/foo/test.Module.nocache.js\">\n");
buf.append("</head></html>");
return buf.toString();
}
}