Author: zhoresh
Date: Wed Jun 15 19:59:43 2011
New Revision: 1136164

URL: http://svn.apache.org/viewvc?rev=1136164&view=rev
Log:
enable closure compiler to work with v2 and higher sourcemap formats | 
http://codereview.appspot.com/4530086/
Patch provide by Vinny.

Modified:
    
shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java
    
shindig/trunk/java/gadgets/src/test/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompilerTest.java

Modified: 
shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java?rev=1136164&r1=1136163&r2=1136164&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/main/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompiler.java
 Wed Jun 15 19:59:43 2011
@@ -19,9 +19,15 @@ package org.apache.shindig.gadgets.rewri
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.debugging.sourcemap.SourceMapping;
+import com.google.debugging.sourcemap.SourceMapConsumerFactory;
+import com.google.debugging.sourcemap.SourceMapParseException;
+import com.google.debugging.sourcemap.proto.Mapping.OriginalMapping;
 import com.google.inject.Inject;
 import com.google.javascript.jscomp.BasicErrorManager;
 import com.google.javascript.jscomp.CheckLevel;
@@ -45,13 +51,8 @@ import org.apache.shindig.gadgets.js.JsR
 import org.apache.shindig.gadgets.js.JsResponseBuilder;
 import org.apache.shindig.gadgets.rewrite.js.JsCompiler;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.StringReader;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -82,6 +83,7 @@ public class ClosureJsCompiler implement
     return result;
   }
 
+  @VisibleForTesting
   protected CompilerOptions getCompilerOptions(JsUri uri) {
     CompilerOptions options = defaultCompilerOptions();
 
@@ -94,7 +96,7 @@ public class ClosureJsCompiler implement
 
   protected void setSourceMapCompilerOptions(CompilerOptions options) {
     options.sourceMapOutputPath = "create.out";
-    options.sourceMapFormat = SourceMap.Format.V1;
+    options.sourceMapFormat = SourceMap.Format.DEFAULT;
     options.sourceMapDetailLevel = SourceMap.DetailLevel.ALL;
   }
 
@@ -173,14 +175,13 @@ public class ClosureJsCompiler implement
     if (outputCorrelatedJs()) {
       // Emit code correlated w/ original source.
       // This operation is equivalent in final code to bundled-output,
-      // but is less efficient and should perhaps only be used in code 
profiling.
-      SourceMappings sm = processSourceMap(result, allContent);
-      if (sm != null) {
-        builder.appendAllJs(sm.mapCompiled(compiled));
+      // but is less efficient and should perhaps only be used in code
+      // profiling.
+      SourceMapParser parser = processSourceMap(result, allContent);
+      if (parser != null) {
+        builder.appendAllJs(parser.mapCompiled(compiled));
       } else {
-        return cacheAndReturnErrorResult(
-            builder, cacheKey,
-            HttpResponse.SC_INTERNAL_SERVER_ERROR,
+        return cacheAndReturnErrorResult(builder, cacheKey, 
HttpResponse.SC_INTERNAL_SERVER_ERROR,
             Lists.newArrayList("Parse error for source map"));
       }
     } else {
@@ -284,122 +285,135 @@ public class ClosureJsCompiler implement
   }
 
   /**
-   * Pull the source map out of the given Closure Result, and convert
-   * it to a local SourceMappings object used to correlate compiled
+   * Pull the source map out of the given closure {@link Result} and construct 
a
+   * {@link SourceMapParser}. This instance can be used to correlate compiled
    * content with originating source.
-   * @param result Closure result object with source map.
-   * @param allInputs All inputs supplied to the compiler, in JsContent form.
-   * @return SourceMappings object correlating compiled with originating input.
+   *
+   * @param result Closure result object with source map
+   * @param allInputs All inputs supplied to the compiler, in JsContent form
+   * @return Utility to parse the sourcemap
    */
-  private SourceMappings processSourceMap(Result result, List<JsContent> 
allInputs) {
+  private SourceMapParser processSourceMap(Result result, List<JsContent> 
allInputs) {
     StringBuilder sb = new StringBuilder();
     try {
-      result.sourceMap.appendTo(sb, "done");
-      return SourceMappings.parseV1(sb.toString(), allInputs);
-    } catch (IOException e) {
-      return null;
-    } catch (JSONException e) {
-      return null;
+      if (result.sourceMap != null) {
+        result.sourceMap.appendTo(sb, "done");
+        return SourceMapParser.parse(sb.toString(), allInputs);
+      }
+    } catch (SourceMapParseException e) { // null response
+    } catch (IOException e) { // null response
     }
+    return null;
   }
 
-  private static class SourceMappings {
+  /**
+   * Parser for the string representation of a {@link SourceMap}.
+   */
+  private static class SourceMapParser {
+    /**
+     * Default source name for constructed {@link JsContent} entries.
+     */
+    private static final String DEFAULT_JSSOURCE = 
"[closure-compiler-synthesized]";
+
+    /**
+     * Utility to parse a {@link SourceMap} string.
+     */
+    private final SourceMapping consumer;
+
+    /**
+     * Map of mapping identifier to code components.
+     */
     private final Map<String, JsContent> orig;
-    private final int[][] lines;
-    private final String[] mappings;
 
-    private SourceMappings(int[][] lines, String[] mappings, List<JsContent> 
content) {
-      this.lines = lines;
-      this.mappings = mappings;
+    private SourceMapParser(SourceMapping consumer, List<JsContent> content) {
+      this.consumer = consumer;
       this.orig = Maps.newHashMap();
       for (JsContent js : content) {
         orig.put(js.getSource(), js);
       }
     }
 
-    private List<JsContent> mapCompiled(String compiled) {
-      List<JsContent> compiledOut = Lists.newLinkedList();
-      int codeStart = 0;
-      int codePos = 0;
-      int curMapping = -1;
-      for (int line = 0; line < lines.length; ++line) {
-        for (int col = 0; col < lines[line].length; ++col) {
-          int nextMapping = lines[line][col];
-          codePos++;
-          if (nextMapping != curMapping && curMapping != -1) {
-            appendJsContent(compiledOut, codeStart, codePos, compiled, 
curMapping);
-            codeStart = codePos;
+    /**
+     * Deconstruct the original javascript content for compiled content.
+     *
+     * This routine iterates through the mapping at every row-column 
combination
+     * of the mapping in order to generate the original content. It is expected
+     * to be a considerably expensive operation.
+     *
+     * @param compiled the compiled javascript
+     * @return {@link JsContent} entries for code fragments belonging to a 
single source
+     */
+    public Iterable<JsContent> mapCompiled(String compiled) {
+      int row = 1, column = 1; // current row-col being parsed
+      StringBuilder codeFragment = new StringBuilder(); // code fragment for a 
single mapping
+
+      OriginalMapping previousMapping = null, // the row-col mapping at the 
previous valid position
+          currentMapping = null; // the row-col mapping at the current valid 
position
+
+      ImmutableList.Builder<JsContent> contentEntries = 
ImmutableList.builder();
+      Iterable<String> compiledLines = Splitter.on("\n").split(compiled);
+      for (String compiledLine : compiledLines) {
+        for (column = 0; column < compiledLine.length(); column++) {
+          currentMapping = consumer.getMappingForLine(row, column + 1);
+          if (!Objects.equal(getSource(currentMapping), 
getSource(previousMapping))) {
+            contentEntries.add(getJsContent(codeFragment.toString(), 
getSource(previousMapping)));
+            codeFragment = new StringBuilder();
           }
-          curMapping = nextMapping;
+          previousMapping = currentMapping;
+          codeFragment.append(compiledLine.charAt(column));
         }
+        row++;
+        codeFragment.append('\n');
       }
-      appendJsContent(compiledOut, codeStart, codePos + 1, compiled, 
curMapping);
-      return compiledOut;
-    }
 
-    private void appendJsContent(List<JsContent> out, int startPos, int 
codePos,
-        String compiled, int mapping) {
-      JsContent sourceJs = orig.get(getRootSrc(mappings[mapping]));
-      String sourceName = "[closure-compiler-synthesized]";
+      // add the last fragment
+      codeFragment.deleteCharAt(codeFragment.length() - 1);
+      if (codeFragment.length() > 0) {
+        contentEntries.add(getJsContent(codeFragment.toString(), 
getSource(previousMapping)));
+      }
+      return contentEntries.build();
+    }
+
+    /**
+     * Utility to get the source of an {@link OriginalMapping}.
+     *
+     * @param mapping the mapping
+     * @return source of the mapping or a blank source if none is present
+     */
+    private final String getSource(OriginalMapping mapping) {
+      return (mapping != null) ? mapping.getOriginalFile() : "";
+    }
+
+    /**
+     * Construct {@link JsContent} instances for a given compiled code
+     * component.
+     *
+     * @param codeFragment the fragment of compiled code for this component
+     * @param mappingIdentifier positional mapping identifier
+     * @return {@link JsContent} for this component
+     */
+    private JsContent getJsContent(String codeFragment, String 
mappingIdentifier) {
+      JsContent sourceJs = orig.get(getRootSrc(mappingIdentifier));
+      String sourceName = DEFAULT_JSSOURCE;
       FeatureBundle bundle = null;
       if (sourceJs != null) {
         sourceName = sourceJs.getSource() != null ? sourceJs.getSource() : "";
         bundle = sourceJs.getFeatureBundle();
       }
-      out.add(JsContent.fromFeature(compiled.substring(startPos, codePos),
-          sourceName, bundle, null));
-    }
-
-    private static final String BEGIN_COMMENT = "/*";
-    private static final String END_COMMENT = "*/";
-    private static SourceMappings parseV1(String sourcemap, List<JsContent> 
orig)
-        throws IOException, JSONException {
-      BufferedReader reader = new BufferedReader(new StringReader(sourcemap));
-      JSONObject summary = new JSONObject(stripComment(reader.readLine()));
-
-      int lineCount = summary.getInt("count");
-
-      // Read lines info.
-      int maxMappingIndex = 0;
-      int[][] lines = new int[lineCount][];
-      for (int i = 0; i < lineCount; ++i) {
-        String lineDescriptor = reader.readLine();
-        JSONArray lineArr = new JSONArray(lineDescriptor);
-        lines[i] = new int[lineArr.length()];
-        for (int j = 0; j < lineArr.length(); ++j) {
-          int mappingIndex = lineArr.getInt(j);
-          lines[i][j] = mappingIndex;
-          maxMappingIndex = Math.max(mappingIndex, maxMappingIndex);
-        }
-      }
-
-      // Bypass comment and unused file info for each line.
-      reader.readLine(); // comment
-      for (int i = 0; i < lineCount; ++i) {
-        reader.readLine();
-      }
-
-      // Read mappings objects.
-      reader.readLine(); // comment
-      String[] mappings = new String[maxMappingIndex + 1];
-      for (int i = 0; i <= maxMappingIndex; ++i) {
-        String mappingLine = reader.readLine();
-        JSONArray mappingObj = new JSONArray(mappingLine);
-        mappings[i] = mappingObj.getString(0);
-      }
-
-      return new SourceMappings(lines, mappings, orig);
+      return JsContent.fromFeature(codeFragment, sourceName, bundle, null);
     }
 
-    private static String stripComment(String line) {
-      int begin = line.indexOf(BEGIN_COMMENT);
-      if (begin != -1) {
-        int end = line.indexOf(END_COMMENT, begin + 1);
-        if (end != -1) {
-          return line.substring(0, begin) + line.substring(end + 
END_COMMENT.length());
-        }
-      }
-      return line;
+    /**
+     * Parse the provided string and return an instance of this parser.
+     *
+     * @param string the {@link SourceMap} in a string representation
+     * @param originalContent the origoinal content
+     * @return parsing utility
+     * @throws SourceMapParseException
+     */
+    public static SourceMapParser parse(String string, List<JsContent> 
originalContent)
+        throws SourceMapParseException {
+      return new SourceMapParser(SourceMapConsumerFactory.parse(string), 
originalContent);
     }
   }
 }

Modified: 
shindig/trunk/java/gadgets/src/test/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompilerTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompilerTest.java?rev=1136164&r1=1136163&r2=1136164&view=diff
==============================================================================
--- 
shindig/trunk/java/gadgets/src/test/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompilerTest.java
 (original)
+++ 
shindig/trunk/java/gadgets/src/test/java16/org/apache/shindig/gadgets/rewrite/js/ClosureJsCompilerTest.java
 Wed Jun 15 19:59:43 2011
@@ -18,11 +18,13 @@
 package org.apache.shindig.gadgets.rewrite.js;
 
 import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createMockBuilder;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.isA;
 import static org.easymock.EasyMock.replay;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.javascript.jscomp.Compiler;
 import com.google.javascript.jscomp.CompilerOptions;
@@ -30,6 +32,8 @@ import com.google.javascript.jscomp.Diag
 import com.google.javascript.jscomp.JSError;
 import com.google.javascript.jscomp.JSSourceFile;
 import com.google.javascript.jscomp.Result;
+import com.google.javascript.jscomp.SourceMap;
+import com.google.javascript.jscomp.SourceMap.Format;
 
 import junit.framework.TestCase;
 
@@ -45,10 +49,29 @@ import org.apache.shindig.gadgets.js.JsR
 import org.apache.shindig.gadgets.rewrite.js.DefaultJsCompiler;
 import org.apache.shindig.gadgets.uri.UriStatus;
 import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.easymock.EasyMock;
 
 import java.util.List;
+import java.util.Map;
 
 public class ClosureJsCompilerTest extends TestCase {
+  private static final String ACTUAL_COMPILER_OUTPUT = "window.abc={};";
+  private static final String EXPORT_COMPILER_STRING = "window['abc'] = {};";
+  private static final Iterable<JsContent> EXPORT_COMPILER_CONTENTS =
+      newJsContents(EXPORT_COMPILER_STRING);
+  private static final List<String> EXPORTS = ImmutableList.of("foo", "bar");
+  private static final String EXTERN = "extern";
+  private static final String ERROR_NAME = "error";
+  private static final JSError JS_ERROR = JSError.make("js", 12, 34,
+      DiagnosticType.error(ERROR_NAME, "errDesc"));
+  private static final Map<String, String> COMPILER_IO = ImmutableMap.<String, 
String>builder()
+      .put("  ", "")
+      .put(EXPORT_COMPILER_STRING, ACTUAL_COMPILER_OUTPUT)
+      .put("var foo = function(x) {}", "var foo=function(x){};")
+      .put("var foo = function(x) { bar(x, x) }; \n var bar = function(x, y) { 
bar(x) };",
+          "var foo=function(x){bar(x,x)};var bar=function(x,y){bar(x)};")
+      .put("", "")
+      .build();
 
   private Compiler realCompMock;
   private CompilerOptions realOptionsMock;
@@ -59,27 +82,11 @@ public class ClosureJsCompilerTest exten
   private CacheProvider cacheMock;
   private ClosureJsCompiler compiler;
 
-  private final String ACTUAL_COMPILER_OUTPUT = "window.abc={};";
-  private final String EXPORT_COMPILER_STRING = "window['abc'] = {};";
-  private final Iterable<JsContent> EXPORT_COMPILER_CONTENTS =
-      newJsContents(EXPORT_COMPILER_STRING);
-
-  private final String CLOSURE_ACTUAL_COMPILER_OUTPUT = ACTUAL_COMPILER_OUTPUT;
-  private final String CLOSURE_EXPORT_COMPILER_OUTPUT = EXPORT_COMPILER_STRING;
-
-  private final List<String> EXPORTS = ImmutableList.of("foo", "bar");
-
-  private final String EXTERN = "extern";
-  private final String ERROR_NAME = "error";
-  private final JSError JS_ERROR = JSError.make(
-      "js", 12, 34, DiagnosticType.error(ERROR_NAME, "errDesc"));
-
-  @Override
   protected void setUp() throws Exception {
     super.setUp();
     cacheMock = new MockProvider();
-    exportResponseMock = mockJsResponse();
-    compilerMock = mockDefaultJsCompiler(exportResponseMock);
+    exportResponseMock = mockJsResponse(EXPORT_COMPILER_STRING);
+    compilerMock = mockDefaultJsCompiler(exportResponseMock, 
EXPORT_COMPILER_CONTENTS);
   }
 
   public void testGetJsContentWithGoogSymbolExports() throws Exception {
@@ -107,21 +114,43 @@ public class ClosureJsCompilerTest exten
     realCompMock = mockRealJsCompiler(null, realResultMock, 
ACTUAL_COMPILER_OUTPUT);
     realOptionsMock = mockRealJsCompilerOptions(false);
     compiler = newClosureJsCompiler(realCompMock, realOptionsMock, 
compilerMock, cacheMock);
-    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS,
-        ImmutableList.of(EXTERN));
-    assertEquals(CLOSURE_ACTUAL_COMPILER_OUTPUT, actual.toJsString());
+    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS, 
EXTERN);
+    assertEquals(ACTUAL_COMPILER_OUTPUT, actual.toJsString());
     assertTrue(actual.getErrors().isEmpty());
   }
 
+  @SuppressWarnings("unchecked")
+  public void testCompileSuccessOptWithProfiling() throws Exception {
+    jsUriMock = mockJsUri(false); // opt
+
+    realOptionsMock = new CompilerOptions();
+    realOptionsMock.enableExternExports(false);
+    realOptionsMock.sourceMapOutputPath = "test.out";
+    realOptionsMock.sourceMapFormat = Format.V2;
+    realOptionsMock.sourceMapDetailLevel = SourceMap.DetailLevel.ALL;
+    realOptionsMock.ideMode = false;
+    realOptionsMock.convertToDottedProperties = true;
+
+    for (Map.Entry<String, String> compilerTest : COMPILER_IO.entrySet()) {
+      List<JsContent> content = newJsContents(compilerTest.getKey());
+      exportResponseMock = mockJsResponse(compilerTest.getKey());
+      compilerMock = mockDefaultJsCompiler(exportResponseMock, content);
+      compiler = newProfilingClosureJsCompiler(realOptionsMock, compilerMock, 
cacheMock);
+
+      JsResponse actual = compiler.compile(jsUriMock, content, EXTERN);
+      assertEquals(compilerTest.getValue(), actual.toJsString());
+      assertTrue(actual.getErrors().isEmpty());
+    }
+  }
+
   public void testCompileSuccessDeb() throws Exception {
     jsUriMock = mockJsUri(true); // debug
     realResultMock = mockRealJsResult();
     realCompMock = mockRealJsCompiler(null, realResultMock, 
ACTUAL_COMPILER_OUTPUT);
     realOptionsMock = mockRealJsCompilerOptions(false);
     compiler = newClosureJsCompiler(realCompMock, realOptionsMock, 
compilerMock, cacheMock);
-    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS,
-        ImmutableList.of(EXTERN));
-    assertEquals(CLOSURE_EXPORT_COMPILER_OUTPUT, actual.toJsString());
+    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS, 
EXTERN);
+    assertEquals(EXPORT_COMPILER_STRING, actual.toJsString());
     assertTrue(actual.getErrors().isEmpty());
   }
 
@@ -130,8 +159,7 @@ public class ClosureJsCompilerTest exten
     realCompMock = mockRealJsCompiler(JS_ERROR, realResultMock, 
ACTUAL_COMPILER_OUTPUT);
     realOptionsMock = mockRealJsCompilerOptions(true); // force compiler to run
     compiler = newClosureJsCompiler(realCompMock, realOptionsMock, 
compilerMock, cacheMock);
-    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS,
-        ImmutableList.of(EXTERN));
+    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS, 
EXTERN);
     assertTrue(actual.getErrors().get(0).contains(ERROR_NAME));
     assertEquals(1, actual.getErrors().size());
   }
@@ -141,53 +169,65 @@ public class ClosureJsCompilerTest exten
     realCompMock = mockRealJsCompiler(JS_ERROR, realResultMock, 
ACTUAL_COMPILER_OUTPUT);
     realOptionsMock = mockRealJsCompilerOptions(true); // force compiler to run
     compiler = newClosureJsCompiler(realCompMock, realOptionsMock, 
compilerMock, cacheMock);
-    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS,
-        ImmutableList.of(EXTERN));
+    JsResponse actual = compiler.compile(jsUriMock, EXPORT_COMPILER_CONTENTS, 
EXTERN);
     assertTrue(actual.getErrors().get(0).contains(ERROR_NAME));
     assertEquals(1, actual.getErrors().size());
   }
 
   private ClosureJsCompiler newClosureJsCompiler(final Compiler realComp,
       CompilerOptions realOptions, DefaultJsCompiler defaultComp, 
CacheProvider cache) {
-    return new ClosureJsCompiler(defaultComp, cache) {
-      @Override
-      Compiler newCompiler() {
-        return realComp;
-      }
-      
-      @Override
-      protected CompilerOptions getCompilerOptions(JsUri uri) {
-        return realOptionsMock;
-      }
-    };
+    ClosureJsCompiler compiler = createMockBuilder(ClosureJsCompiler.class)
+        .addMockedMethods("newCompiler", "getCompilerOptions", 
"outputCorrelatedJs")
+        .withConstructor(defaultComp, cache)
+        .createMock();
+    expect(compiler.newCompiler()).andReturn(realComp).anyTimes();
+    
expect(compiler.getCompilerOptions(isA(JsUri.class))).andReturn(realOptionsMock).anyTimes();
+    expect(compiler.outputCorrelatedJs()).andReturn(false).anyTimes();
+    replay(compiler);
+    return compiler;
+  }
+
+  private ClosureJsCompiler newProfilingClosureJsCompiler(CompilerOptions 
realOptions,
+      DefaultJsCompiler defaultComp, CacheProvider cache) {
+    ClosureJsCompiler compiler =
+        createMockBuilder(ClosureJsCompiler.class)
+            .addMockedMethods("getCompilerOptions", "outputCorrelatedJs")
+            .withConstructor(defaultComp, cache).createMock();
+    
expect(compiler.getCompilerOptions(isA(JsUri.class))).andReturn(realOptions).anyTimes();
+    expect(compiler.outputCorrelatedJs()).andReturn(true).anyTimes();
+    replay(compiler);
+    return compiler;
   }
 
-  private JsResponse mockJsResponse() {
+  private JsResponse mockJsResponse(String content) {
     JsResponse result = createMock(JsResponse.class);
-    expect(result.toJsString()).andReturn(EXPORT_COMPILER_STRING).anyTimes();
-    
expect(result.getAllJsContent()).andReturn(EXPORT_COMPILER_CONTENTS).anyTimes();
+    expect(result.toJsString()).andReturn(content).anyTimes();
+    
expect(result.getAllJsContent()).andReturn(newJsContents(content)).anyTimes();
     replay(result);
     return result;
   }
 
   @SuppressWarnings("unchecked")
-  private DefaultJsCompiler mockDefaultJsCompiler(JsResponse res) {
+  private DefaultJsCompiler mockDefaultJsCompiler(JsResponse res, 
Iterable<JsContent> content) {
     DefaultJsCompiler result = createMock(DefaultJsCompiler.class);
     expect(result.getJsContent(isA(JsUri.class), isA(FeatureBundle.class)))
-        .andReturn(EXPORT_COMPILER_CONTENTS).anyTimes();
-    expect(result.compile(isA(JsUri.class), isA(Iterable.class), 
isA(List.class)))
+        .andReturn(content).anyTimes();
+    expect(result.compile(isA(JsUri.class), isA(Iterable.class), 
isA(String.class)))
         .andReturn(res).anyTimes();
     replay(result);
     return result;
   }
 
   private Result mockRealJsResult() {
-    return createMock(Result.class);
+    Result result = createMock(Result.class);
+    replay(result);
+    return result;
   }
 
   private Compiler mockRealJsCompiler(JSError error, Result res, String 
toSource) {
     Compiler result = createMock(Compiler.class);
-    expect(result.compile(isA(JSSourceFile[].class), isA(JSSourceFile[].class),
+    expect(result.compile(EasyMock.<List<JSSourceFile>>anyObject(),
+        EasyMock.<List<JSSourceFile>>anyObject(),
         isA(CompilerOptions.class))).andReturn(res);
     if (error != null) {
       expect(result.hasErrors()).andReturn(true);
@@ -217,13 +257,15 @@ public class ClosureJsCompilerTest exten
     
expect(result.getContext()).andReturn(RenderingContext.CONFIGURED_GADGET).anyTimes();
     expect(result.getRefresh()).andReturn(1000).anyTimes();
     expect(result.isNoCache()).andReturn(false).anyTimes();
-    expect(result.getGadget()).andReturn("http://foo.com/g.xml";).anyTimes();
+    expect(result.getGadget()).andReturn("http://foo.com/g.xml";).anyTimes();   
 
     expect(result.getLibs()).andReturn(ImmutableList.<String>of()).anyTimes();
     
expect(result.getLoadedLibs()).andReturn(ImmutableList.<String>of()).anyTimes();
     expect(result.getOnload()).andReturn("foo").anyTimes();
     expect(result.isJsload()).andReturn(true).anyTimes();
     expect(result.isNohint()).andReturn(true).anyTimes();
     expect(result.getOrigUri()).andReturn(null).anyTimes();
+    expect(result.getRepository()).andReturn(null).anyTimes();
+    expect(result.getExtensionParams()).andReturn(null).anyTimes();
     replay(result);
     return result;
   }
@@ -252,7 +294,7 @@ public class ClosureJsCompilerTest exten
 
   private static List<JsContent> newJsContents(String jsCode) {
     List<JsContent> result = Lists.newArrayList();
-    result.add(JsContent.fromText(jsCode, null));
+    result.add(JsContent.fromText(jsCode, "testSource"));
     return result;
   }
 }


Reply via email to