public void testAssociateNode() { String message = "Some error happened."; Throwable cause = new Throwable(); SoySyntaxException sse = SoySyntaxException.createCausedWithoutMetaInfo(message, cause); String testFileContent = "{namespace boo}\n" + "\n" + "/** @param goo */\n" + "{template name=\".foo\"}\n" + " {$goo}\n" + "{/template}\n"; SoyFileSetNode soyTree = SharedTestUtils.parseSoyFiles(testFileContent); PrintNode pn = (PrintNode) soyTree.getChild(0).getChild(0).getChild(0); // Before. assertTrue(sse.getMessage().contains(message)); assertEquals(cause, sse.getCause()); assertEquals("unknown", sse.getSourceLocation().getFilePath()); assertEquals(null, sse.getTemplateName()); SoySyntaxExceptionUtils.associateNode(sse, pn); // After. assertTrue(sse.getMessage().contains(message)); assertEquals(cause, sse.getCause()); assertEquals("no-path", sse.getSourceLocation().getFilePath()); assertEquals("boo.foo", sse.getTemplateName()); }
private void assertParseError(String typeInput, String msg) { try { parseType(typeInput); fail("Input string '" + typeInput + "' should have failed to parse."); } catch (SoySyntaxException e) { assertThat(e.getMessage()).isEqualTo(msg); } }
private void assertCheckIcuEscapingIsNotNeededFails( String rawText, String expectedErrorMsgSubstr) { try { IcuSyntaxUtils.checkIcuEscapingIsNotNeeded(rawText); fail(); } catch (SoySyntaxException sse) { assertThat(sse.getMessage()).contains(expectedErrorMsgSubstr); } }
/** Private helper for {@code testGenNoncollidingBaseNames()}. */ private void assertErrorMsgWhenGenNoncollidingBaseNamesForExprs( String expectedErrorMsg, String exprListText) { List<ExprRootNode<?>> exprRoots = ExprParseUtils.parseExprListElseThrowSoySyntaxException(exprListText, ""); try { MsgSubstUnitBaseVarNameUtils.genNoncollidingBaseNamesForExprs(exprRoots, "FALLBACK"); MsgNodeTest.fail(); } catch (SoySyntaxException sse) { MsgNodeTest.assertTrue(sse.getMessage().contains(expectedErrorMsg)); } }
/** * Assertions function that checks to make sure that name resolution fails with the expected * exception. * * @param fileContent The template source. * @param expectedError The expected failure message (a substring). */ private void assertResolveExpressionTypesFails(String expectedError, String fileContent) { SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(fileContent) .declaredSyntaxVersion(SyntaxVersion.V2_0) .doRunInitialParsingPasses(false) .typeRegistry(typeRegistry) .parse(); createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree); try { createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree); fail("Expected SoySyntaxException"); } catch (SoySyntaxException e) { assertThat(e.getMessage()).contains(expectedError); } catch (IllegalStateException e) { // from the exploding error reporter assertThat(e.getMessage()).startsWith("Unexpected SoyError:"); assertThat(e.getMessage()).contains(expectedError); } }
public void testAssertNoUnboundGlobals() throws Exception { ExprRootNode<?> expr = (new ExpressionParser("BOO + 'aaa' + foo.GOO")).parseExpression(); Map<String, PrimitiveData> globals = ImmutableMap.<String, PrimitiveData>of( "BOO", StringData.forValue("boo"), "GOO", StringData.forValue("goo"), "foo.MOO", StringData.forValue("moo")); try { ((new SubstituteGlobalsVisitor(globals, null, true)).new SubstituteGlobalsInExprVisitor()) .exec(expr); fail(); } catch (SoySyntaxException sse) { assertTrue(sse.getMessage().contains("Found unbound global 'foo.GOO'.")); } }
/** Performs checks that only involve templates (uses templateRegistry only). */ private void checkTemplates() { Map<String, TemplateBasicNode> basicTemplatesMap = templateRegistry.getBasicTemplatesMap(); Map<DelTemplateKey, List<DelegateTemplateDivision>> delTemplatesMap = templateRegistry.getDelTemplatesMap(); Map<String, Set<DelTemplateKey>> delTemplateNameToKeysMap = templateRegistry.getDelTemplateNameToKeysMap(); // Check that no name is reused for both basic and delegate templates. Set<String> reusedTemplateNames = Sets.newLinkedHashSet(); for (DelTemplateKey delTemplateKey : delTemplatesMap.keySet()) { if (basicTemplatesMap.containsKey(delTemplateKey.name)) { reusedTemplateNames.add(delTemplateKey.name); } } if (reusedTemplateNames.size() > 0) { throw SoySyntaxException.createWithoutMetaInfo( "Found template name " + reusedTemplateNames + " being reused for both basic and" + " delegate templates."); } // Check that all delegate templates with the same name have the same declared params and // content kind. First, we iterate over template names: for (Set<DelTemplateKey> delTemplateKeys : delTemplateNameToKeysMap.values()) { TemplateDelegateNode firstDelTemplate = null; Set<TemplateParam> firstParamSet = null; ContentKind firstContentKind = null; // Then, loop over keys that share the same name (effectively, over variants): for (DelTemplateKey delTemplateKey : delTemplateKeys) { // Then, loop over divisions with the same key (effectively, over priorities): for (DelegateTemplateDivision division : delTemplatesMap.get(delTemplateKey)) { // Now, over templates in the division (effectively, delpackages): for (TemplateDelegateNode delTemplate : division.delPackageNameToDelTemplateMap.values()) { String currDelPackageName = (delTemplate.getDelPackageName() != null) ? delTemplate.getDelPackageName() : "<default>"; if (firstDelTemplate == null) { // First template encountered. firstDelTemplate = delTemplate; firstParamSet = Sets.newHashSet(delTemplate.getParams()); firstContentKind = delTemplate.getContentKind(); } else { // Not first template encountered. Set<TemplateParam> currParamSet = Sets.newHashSet(delTemplate.getParams()); if (!currParamSet.equals(firstParamSet)) { throw SoySyntaxExceptionUtils.createWithNode( String.format( "Found delegate template with same name '%s' but different param" + " declarations compared to the definition at %s.", firstDelTemplate.getDelTemplateName(), firstDelTemplate.getSourceLocation().toString()), delTemplate); } if (delTemplate.getContentKind() != firstContentKind) { // TODO: This is only *truly* a requirement if the strict mode deltemplates are // being called by contextual templates. For a strict-to-strict call, everything // is escaped at runtime at the call sites. You could imagine delegating between // either a plain-text or rich-html template. However, most developers will write // their deltemplates in a parallel manner, and will want to know when the // templates differ. Plus, requiring them all to be the same early-on will allow // future optimizations to avoid the run-time checks, so it's better to start out // as strict as possible and only open up if needed. throw SoySyntaxExceptionUtils.createWithNode( String.format( "If one deltemplate has strict autoescaping, all its peers must also be " + "strictly autoescaped with the same content kind: %s != %s. " + "Conflicting definition at %s.", firstContentKind, delTemplate.getContentKind(), firstDelTemplate.getSourceLocation().toString()), delTemplate); } } } } } } }