Package com.google.template.soy.soyparse

Source Code of com.google.template.soy.soyparse.SourceLocationTest$AsciiArtVisitor

/*
* 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.template.soy.soyparse;

import com.google.common.base.Joiner;
import com.google.template.soy.base.SoyFileKind;
import com.google.template.soy.base.SoyFileSupplier;
import com.google.template.soy.base.SoySyntaxException;
import com.google.template.soy.soytree.AbstractSoyNodeVisitor;
import com.google.template.soy.soytree.SoyFileSetNode;
import com.google.template.soy.soytree.SoyNode;
import com.google.template.soy.soytree.SoyNode.ParentSoyNode;

import junit.framework.TestCase;

/**
* Tests that the Soy file and template parsers properly embed source locations.
*/
public class SourceLocationTest extends TestCase {
  public final void testLocationsInParsedContent() throws Exception {
    assertSourceLocations(
        Joiner.on('\n').join(
            "SoyFileSetNode                 @ unknown",
            "  SoyFileNode                  @ /example/file.soy",
            "    TemplateBasicNode          @ /example/file.soy:1",
            "      RawTextNode              @ /example/file.soy:2",
            "      PrintNode                @ /example/file.soy:4",
            "      RawTextNode              @ /example/file.soy:5",
            "      CallBasicNode            @ /example/file.soy:7",
            "    TemplateBasicNode          @ /example/file.soy:9",
            "      RawTextNode              @ /example/file.soy:10",
            ""),
        "/example/file.soy",
        Joiner.on('\n').join(
            "{template foo}",     // 1
            "  Hello",            // 2
            "  {lb}",             // 3
            "  {print $world}",   // 4
            "  {rb}!",            // 5
            "",                   // 6
            "  {call bar /}",     // 7
            "{/template}",        // 8
            "{template bar}",     // 9
            "  Gooodbye",         // 10
            "{/template}"         // 11
            )
        );
  }

  public final void testSwitches() throws Exception {
    assertSourceLocations(
        Joiner.on('\n').join(
            "SoyFileSetNode                 @ unknown",
            "  SoyFileNode                  @ /example/file.soy",
            "    TemplateBasicNode          @ /example/file.soy:1",
            "      RawTextNode              @ /example/file.soy:2",
            "      SwitchNode               @ /example/file.soy:3",
            "        SwitchCaseNode         @ /example/file.soy:4",
            "          RawTextNode          @ /example/file.soy:5",
            "        SwitchCaseNode         @ /example/file.soy:6",
            "          RawTextNode          @ /example/file.soy:7",
            "        SwitchCaseNode         @ /example/file.soy:8",
            "          RawTextNode          @ /example/file.soy:9",
            "        SwitchDefaultNode      @ /example/file.soy:10",
            "          RawTextNode          @ /example/file.soy:11",
            "      RawTextNode              @ /example/file.soy:13",
            ""),
        "/example/file.soy",
        Joiner.on('\n').join(
            "{template foo}"// 1
            "  Hello,",        // 2
            "  {switch $i}",   // 3
            "    {case 0}",    // 4
            "      Mercury",   // 5
            "    {case 1}",    // 6
            "      Venus",     // 7
            "    {case 2}",    // 8
            "      Mars",      // 9
            "    {default}",   // 10
            "      Gassy",     // 11
            "  {/switch}",     // 12
            "  !",             // 13
            "{/template}",     // 14
            "")
        );
  }

  public final void testForLoop() throws Exception {
    assertSourceLocations(
        Joiner.on('\n').join(
            "SoyFileSetNode                 @ unknown",
            "  SoyFileNode                  @ /example/file.soy",
            "    TemplateBasicNode          @ /example/file.soy:1",
            "      RawTextNode              @ /example/file.soy:2",
            "      ForNode                  @ /example/file.soy:3",
            "        RawTextNode            @ /example/file.soy:4",
            "        PrintNode              @ /example/file.soy:5",
            "      RawTextNode              @ /example/file.soy:7",
            ""),
        "/example/file.soy",
        Joiner.on('\n').join(
            "{template foo}",                   // 1
            "  Hello",                          // 2
            "  {for $i in range($s, $e, $t)}"// 3
            "    ,",                            // 4
            "    {print $planet[$i]}",          // 5
            "  {/for}",                         // 6
            "  !",                              // 7
            "{/template}",                      // 8
            "")
        );
  }

  public final void testForeachLoop() throws Exception {
    assertSourceLocations(
        Joiner.on('\n').join(
            "SoyFileSetNode                 @ unknown",
            "  SoyFileNode                  @ /example/file.soy",
            "    TemplateBasicNode          @ /example/file.soy:1",
            "      RawTextNode              @ /example/file.soy:2",
            "      ForeachNode              @ /example/file.soy:3",
            "        ForeachNonemptyNode    @ /example/file.soy:3",
            "          RawTextNode          @ /example/file.soy:4",
            "          PrintNode            @ /example/file.soy:5",
            "        ForeachIfemptyNode     @ /example/file.soy:6",
            "          RawTextNode          @ /example/file.soy:7",
            "      RawTextNode              @ /example/file.soy:9",
            ""),
        "/example/file.soy",
        Joiner.on('\n').join(
            "{template foo}",                   // 1
            "  Hello",                          // 2
            "  {foreach $planet in $planets}"// 3
            "    ,",                            // 4
            "    {print $planet[$i]}",          // 5
            "  {ifempty}",                      // 6
            "    lifeless interstellar void",   // 7
            "  {/foreach}",                     // 8
            "  !",                              // 9
            "{/template}",                      // 10
            "")
        );
  }

  public final void testConditional() throws Exception {
    assertSourceLocations(
        Joiner.on('\n').join(
            "SoyFileSetNode                 @ unknown",
            "  SoyFileNode                  @ /example/file.soy",
            "    TemplateBasicNode          @ /example/file.soy:1",
            "      RawTextNode              @ /example/file.soy:2",
            "      IfNode                   @ /example/file.soy:3",
            "        IfCondNode             @ /example/file.soy:3",
            "          RawTextNode          @ /example/file.soy:4",
            "        IfCondNode             @ /example/file.soy:5",
            "          RawTextNode          @ /example/file.soy:6",
            "        IfElseNode             @ /example/file.soy:7",
            "          RawTextNode          @ /example/file.soy:8",
            "      RawTextNode              @ /example/file.soy:10",
            ""),
        "/example/file.soy",
        Joiner.on('\n').join(
            "{template foo}",                 // 1
            "  Hello,",                       // 2
            "  {if $skyIsBlue}",              // 3
            "    Earth",                      // 4
            "  {elseif $isReallyReallyHot}"// 5
            "    Venus",                      // 6
            "  {else}",                       // 7
            "    Cincinatti",                 // 8
            "  {/if}",                        // 9
            "  !",                            // 10
            "{/template}",                    // 11
            "")
        );
  }

  public final void testDoesntAccessPastEnd() {
    // Make sure that if we have a token stream that ends abruptly, we don't
    // look for a line number and break in a way that suppresses the real error
    // message.
    // JavaCC is pretty good about never using null as a token value.
    try {
      (new SoyFileSetParser(
          SoyFileSupplier.Factory.create(
              "{template t}\nHello, World!\n", SoyFileKind.SRC, "borken.soy")))
          .setDoRunInitialParsingPasses(false)
          .parse();
    } catch (SoySyntaxException ex) {
      // OK
      return;
    }
  }


  void assertSourceLocations(
      String asciiArtExpectedOutput, String soySourcePath, String soySourceCode)
      throws Exception {

    SoyFileSetNode soyTree =
        (new SoyFileSetParser(SoyFileSupplier.Factory.create(
            soySourceCode, SoyFileKind.SRC, soySourcePath)))
            .setDoRunInitialParsingPasses(false)
            .parse();

    String actual = new AsciiArtVisitor().exec(soyTree);
    assertEquals(asciiArtExpectedOutput, actual);
  }


  /**
   * Generates a concise readable summary of a soy tree and its source locations.
   */
  static class AsciiArtVisitor extends AbstractSoyNodeVisitor<String> {
    final StringBuilder sb = new StringBuilder();
    int depth;

    @Override public String exec(SoyNode node) {
      visit(node);
      return sb.toString();
    }

    @Override protected void visitSoyNode(SoyNode node) {
      // Output a header like:
      //   <indent> <node class>                    @ <location>
      // where indent is 2 spaces per level, and the @ sign is indented to the 31st column.
      for (int indent = depth; --indent >= 0;) {
        sb.append("  ");
      }
      String typeName = node.getClass().getSimpleName();
      sb.append(typeName);
      int pos = typeName.length() + 2 * depth;
      while (pos < 30) {
        sb.append(' ');
        ++pos;
      }
      sb.append(" @ ").append(node.getSourceLocation()).append('\n');

      if (node instanceof ParentSoyNode<?>) {
        ++depth;
        visitChildren((ParentSoyNode<?>) node);
        --depth;
      }
    }
  }
}
TOP

Related Classes of com.google.template.soy.soyparse.SourceLocationTest$AsciiArtVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.