/* * Copyright 2009 The Closure Compiler Authors. * * 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.debugging.sourcemap; import com.google.javascript.jscomp.SourceMap; import com.google.javascript.jscomp.SourceMap.Format; /** * Tests for {@link SourceMap}. * */ public class SourceMapGeneratorV1Test extends SourceMapTestCase { public SourceMapGeneratorV1Test() { disableColumnValidation(); } @Override protected SourceMapConsumer getSourceMapConsumer() { return new SourceMapConsumerV1(); } @Override protected Format getSourceMapFormat() { return SourceMap.Format.V1; } @Override public void setUp() { detailLevel = SourceMap.DetailLevel.ALL; } public void testBasicMapping() throws Exception { compileAndCheck("function __BASIC__() { }"); } public void testLiteralMappings() throws Exception { compileAndCheck("function __BASIC__(__PARAM1__, __PARAM2__) { " + "var __VAR__ = '__STR__'; }"); } public void testMultilineMapping() throws Exception { compileAndCheck("function __BASIC__(__PARAM1__, __PARAM2__) {\n" + "var __VAR__ = '__STR__';\n" + "var __ANO__ = \"__STR2__\";\n" + "}"); } public void testMultiFunctionMapping() throws Exception { compileAndCheck("function __BASIC__(__PARAM1__, __PARAM2__) {\n" + "var __VAR__ = '__STR__';\n" + "var __ANO__ = \"__STR2__\";\n" + "}\n\n" + "function __BASIC2__(__PARAM3__, __PARAM4__) {\n" + "var __VAR2__ = '__STR2__';\n" + "var __ANO2__ = \"__STR3__\";\n" + "}\n\n"); } public void testGoldenOutput0() throws Exception { // Empty source map test checkSourceMap("", "/** Begin line maps. **/{ \"file\" : \"testcode\"," + " \"count\": 1 }\n" + "[]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n"); } public void testFunctionNameOutput1() throws Exception { checkSourceMap("function f() {}", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,0,0,0,0,0,0,1,1,2,2,3,3]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,0,\"f\"]\n" + "[\"testcode\",1,9,\"f\"]\n" + "[\"testcode\",1,10]\n" + "[\"testcode\",1,13]\n"); } public void testFunctionNameOutput2() throws Exception { checkSourceMap("a.b.c = function () {};", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[3,2,2,1,1,0,4,4,4,4,4,4,4,4,5,5,6,6]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,0]\n" + "[\"testcode\",1,0,\"c\"]\n" + "[\"testcode\",1,0,\"b\"]\n" + "[\"testcode\",1,0,\"a\"]\n" + "[\"testcode\",1,8,\"a.b.c\"]\n" + "[\"testcode\",1,17]\n" + "[\"testcode\",1,20]\n"); } public void testFunctionNameOutput3() throws Exception { checkSourceMap("var q = function () {};", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,0,0,1,1,2,2,2,2,2,2,2,2,3,3,4,4]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,0]\n" + "[\"testcode\",1,4,\"q\"]\n" + "[\"testcode\",1,8,\"q\"]\n" + "[\"testcode\",1,17]\n" + "[\"testcode\",1,20]\n"); } public void testFunctionNameOutput4() throws Exception { checkSourceMap("({ 'q' : function () {} })", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,1,1,1,0,2,2,2,2,2,2,2,2,3,3,4,4,0,0]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,1]\n" + "[\"testcode\",1,3]\n" + "[\"testcode\",1,9,\"q\"]\n" + "[\"testcode\",1,18]\n" + "[\"testcode\",1,21]\n"); } public void testGoldenOutput1() throws Exception { detailLevel = SourceMap.DetailLevel.ALL; checkSourceMap("function f(foo, bar) { foo = foo + bar + 2; return foo; }", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,0,0,0,0,0,0,1,1,2,3,3,3,2,4,4,4,2,5,7,7,7,6,8,8,8,6," + "9,9,9,6,10,11,11,11,11,11,11,11,12,12,12,12,5]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,0,\"f\"]\n" + "[\"testcode\",1,9,\"f\"]\n" + "[\"testcode\",1,10]\n" + "[\"testcode\",1,11,\"foo\"]\n" + "[\"testcode\",1,16,\"bar\"]\n" + "[\"testcode\",1,21]\n" + "[\"testcode\",1,23]\n" + "[\"testcode\",1,23,\"foo\"]\n" + "[\"testcode\",1,29,\"foo\"]\n" + "[\"testcode\",1,35,\"bar\"]\n" + "[\"testcode\",1,41]\n" + "[\"testcode\",1,44]\n" + "[\"testcode\",1,51,\"foo\"]\n"); detailLevel = SourceMap.DetailLevel.SYMBOLS; checkSourceMap("function f(foo, bar) { foo = foo + bar + 2; return foo; }", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,0,0,0,0,0,0,1,1,0,2,2,2,0,3,3,3,0,0,4,4,4,0,5,5,5,0," + "6,6,6,0,0,0,0,0,0,0,0,0,7,7,7,7,0]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,0,\"f\"]\n" + "[\"testcode\",1,9,\"f\"]\n" + "[\"testcode\",1,11,\"foo\"]\n" + "[\"testcode\",1,16,\"bar\"]\n" + "[\"testcode\",1,23,\"foo\"]\n" + "[\"testcode\",1,29,\"foo\"]\n" + "[\"testcode\",1,35,\"bar\"]\n" + "[\"testcode\",1,51,\"foo\"]\n"); } public void testGoldenOutput2() throws Exception { checkSourceMap("function f(foo, bar) {\r\n\n\n\nfoo = foo + bar + foo;" + "\nreturn foo;\n}", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,0,0,0,0,0,0,1,1,2,3,3,3,2,4,4,4,2,5,7,7,7,6,8,8,8," + "6,9,9,9,6,10,10,10,11,11,11,11,11,11,11,12,12,12," + "12,5]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"testcode\",1,0,\"f\"]\n" + "[\"testcode\",1,9,\"f\"]\n" + "[\"testcode\",1,10]\n" + "[\"testcode\",1,11,\"foo\"]\n" + "[\"testcode\",1,16,\"bar\"]\n" + "[\"testcode\",1,21]\n" + "[\"testcode\",5,0]\n" + "[\"testcode\",5,0,\"foo\"]\n" + "[\"testcode\",5,6,\"foo\"]\n" + "[\"testcode\",5,12,\"bar\"]\n" + "[\"testcode\",5,18,\"foo\"]\n" + "[\"testcode\",6,0]\n" + "[\"testcode\",6,7,\"foo\"]\n"); } public void testGoldenOutput3() throws Exception { checkSourceMap("c:\\myfile.js", "foo;", "/** Begin line maps. **/{ \"file\" : \"testcode\", " + "\"count\": 1 }\n" + "[0,0,0]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"c:\\\\myfile.js\",1,0,\"foo\"]\n"); } public void testGoldenOutput4() throws Exception { checkSourceMap("c:\\myfile.js", "foo; boo; goo;", "/** Begin line maps. **/" + "{ \"file\" : \"testcode\", \"count\": 1 }\n" + "[0,0,0,1,1,1,1,2,2,2,2]\n" + "/** Begin file information. **/\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"c:\\\\myfile.js\",1,0,\"foo\"]\n" + "[\"c:\\\\myfile.js\",1,7,\"boo\"]\n" + "[\"c:\\\\myfile.js\",1,14,\"goo\"]\n"); } public void testGoldenOutput5() throws Exception { detailLevel = SourceMap.DetailLevel.ALL; checkSourceMap("c:\\myfile.js", "/** @preserve\n" + " * this is a test.\n" + " */\n" + "var foo=a + 'this is a really long line that will force the" + " mapping to span multiple lines 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + "' + c + d + e;", "/** Begin line maps. **/" + "{ \"file\" : \"testcode\", \"count\": 6 }\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "[0,0,0,0,1,1,1,1,2,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3," + "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]\n" + "[4,1,5,1,6]\n" + "/** Begin file information. **/\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"c:\\\\myfile.js\",4,0]\n" + "[\"c:\\\\myfile.js\",4,4,\"foo\"]\n" + "[\"c:\\\\myfile.js\",4,8,\"a\"]\n" + "[\"c:\\\\myfile.js\",4,12]\n" + "[\"c:\\\\myfile.js\",4,1314,\"c\"]\n" + "[\"c:\\\\myfile.js\",4,1318,\"d\"]\n" + "[\"c:\\\\myfile.js\",4,1322,\"e\"]\n"); detailLevel = SourceMap.DetailLevel.SYMBOLS; checkSourceMap("c:\\myfile.js", "/** @preserve\n" + " * this is a test.\n" + " */\n" + "var foo=a + 'this is a really long line that will force the" + " mapping to span multiple lines 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + " 123456789 123456789 123456789 123456789 123456789" + "' + c + d + e;", "/** Begin line maps. **/" + "{ \"file\" : \"testcode\", \"count\": 6 }\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "[-1,-1,-1,-1,0,0,0,0,1]\n" + "[2,0,3,0,4]\n" + "/** Begin file information. **/\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "[]\n" + "/** Begin mapping definitions. **/\n" + "[\"c:\\\\myfile.js\",4,4,\"foo\"]\n" + "[\"c:\\\\myfile.js\",4,8,\"a\"]\n" + "[\"c:\\\\myfile.js\",4,1314,\"c\"]\n" + "[\"c:\\\\myfile.js\",4,1318,\"d\"]\n" + "[\"c:\\\\myfile.js\",4,1322,\"e\"]\n"); } public void testBasicDeterminism() throws Exception { RunResult result1 = compile("file1", "foo;", "file2", "bar;"); RunResult result2 = compile("file2", "foo;", "file1", "bar;"); String map1 = getSourceMap(result1); String map2 = getSourceMap(result2); // Assert that the files section of the maps are the same. The actual // entries will differ, so we cannot do a simple full comparison. // Line 5 has the file information. String files1 = map1.split("\n")[4]; String files2 = map2.split("\n")[4]; assertEquals(files1, files2); } }