| /* |
| * 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(); |
| } |
| } |