package com.hubspot.jinjava.lib.tag;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.SetMultimap;
import com.google.common.io.Resources;
import com.hubspot.jinjava.Jinjava;
import com.hubspot.jinjava.JinjavaConfig;
import com.hubspot.jinjava.interpret.TagCycleException;
import com.hubspot.jinjava.interpret.FatalTemplateErrorsException;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.RenderResult;
import com.hubspot.jinjava.loader.ResourceLocator;
public class ExtendsTagTest {
private ExtendsTagTestResourceLocator locator;
private Jinjava jinjava;
@Before
public void setup() {
locator = new ExtendsTagTestResourceLocator();
JinjavaConfig conf = new JinjavaConfig();
jinjava = new Jinjava(conf);
jinjava.setResourceLocator(locator);
}
@Test
public void singleExtendsTag() throws Exception {
String result = jinjava.render(locator.fixture("extends-base1.jinja"), new HashMap<String, Object>());
Document dom = Jsoup.parse(result);
assertThat(dom.select(".important").get(0).text()).isEqualTo("Welcome on my awesome homepage.");
}
@Test
public void nestedExtendsHierarchy() throws Exception {
String result = jinjava.render(locator.fixture("extends-base2.jinja"), new HashMap<String, Object>());
Document dom = Jsoup.parse(result);
assertThat(dom.select(".important").get(0).text()).isEqualTo("foobar");
}
@Test
public void parentTemplateImportsVarsUsedInChild() throws Exception {
Document dom = Jsoup.parse(jinjava.render(locator.fixture("parentvars-child.html"), new HashMap<String, Object>()));
assertThat(dom.select("body").attr("bgcolor")).isEqualTo("#f5f5f5");
assertThat(dom.select("p.foo").text()).isEqualTo("bar");
}
@Test
public void extendsWithSuperCall() throws Exception {
Document dom = Jsoup.parse(jinjava.render(locator.fixture("super-child.html"), new HashMap<String, Object>()));
assertThat(dom.select(".sidebar p").text()).isEqualTo("this is a sidebar.");
assertThat(dom.select(".sidebar h3").text()).isEqualTo("Table Of Contents");
}
@Test
public void itHasExtendsReferenceInContext() throws Exception {
RenderResult renderResult = jinjava.renderForResult(locator.fixture("super-child.html"), new HashMap<String, Object>());
SetMultimap<String, String> dependencies = renderResult.getContext().getDependencies();
assertThat(dependencies.size()).isEqualTo(1);
assertThat(dependencies.get("coded_files")).isNotEmpty();
assertThat(dependencies.get("coded_files").contains("super-base.html"));
}
@Test
public void itAvoidsSimpleExtendsCycles() throws IOException {
try {
jinjava.render(locator.fixture("extends-self.jinja"),
new HashMap<String, Object>());
fail("expected extends tag cycle exception");
} catch (FatalTemplateErrorsException e) {
TagCycleException cycleException = (TagCycleException) e.getErrors().iterator().next().getException();
assertThat(cycleException.getPath()).isEqualTo("extends-self.jinja");
}
}
@Test
public void itAvoidsNestedExtendsCycles() throws IOException {
try {
jinjava.render(locator.fixture("a-extends-b.jinja"),
new HashMap<String, Object>());
fail("expected extends tag cycle exception");
} catch (FatalTemplateErrorsException e) {
TagCycleException cycleException = (TagCycleException) e.getErrors().iterator().next().getException();
assertThat(cycleException.getPath()).isEqualTo("b-extends-a.jinja");
}
}
private static class ExtendsTagTestResourceLocator implements ResourceLocator {
@Override
public String getString(String fullName, Charset encoding, JinjavaInterpreter interpreter) throws IOException {
return fixture(fullName);
}
public String fixture(String name) throws IOException {
return Resources.toString(Resources.getResource(String.format("tags/extendstag/%s", name)), StandardCharsets.UTF_8);
}
}
}