Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/main/java/com/hubspot/jinjava/lib/tag/FromTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,15 @@ public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
Map<String, String> imports = getImportMap(helper);

try {
Node node = ImportTag.parseTemplateAsNode(interpreter, templateFile);
String template = interpreter.getResource(templateFile);
Node node = interpreter.parse(template);

JinjavaInterpreter child = interpreter
.getConfig()
.getInterpreterFactory()
.newInstance(interpreter);
child.getContext().put(Context.IMPORT_RESOURCE_PATH_KEY, templateFile);

JinjavaInterpreter.pushCurrent(child);

try {
child.render(node);
} finally {
Expand Down Expand Up @@ -126,7 +125,6 @@ public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) {
}
} finally {
interpreter.getContext().popFromStack();
interpreter.getContext().getCurrentPathStack().pop();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.hubspot.jinjava.lib.fn.eager.EagerMacroFunction;
import com.hubspot.jinjava.lib.tag.DoTag;
import com.hubspot.jinjava.lib.tag.FromTag;
import com.hubspot.jinjava.lib.tag.ImportTag;
import com.hubspot.jinjava.lib.tag.eager.importing.EagerImportingStrategyFactory;
import com.hubspot.jinjava.tree.Node;
import com.hubspot.jinjava.tree.parse.TagToken;
Expand Down Expand Up @@ -82,7 +81,8 @@ public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter
String templateFile = maybeTemplateFile.get();
try {
try {
Node node = ImportTag.parseTemplateAsNode(interpreter, templateFile);
String template = interpreter.getResource(templateFile);
Node node = interpreter.parse(template);

JinjavaInterpreter child = interpreter
.getConfig()
Expand Down Expand Up @@ -138,7 +138,6 @@ public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter
}
} finally {
interpreter.getContext().popFromStack();
interpreter.getContext().getCurrentPathStack().pop();
}
}

Expand Down
204 changes: 8 additions & 196 deletions src/test/java/com/hubspot/jinjava/lib/tag/FromTagTest.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.hubspot.jinjava.lib.tag;

import static com.hubspot.jinjava.lib.tag.ResourceLocatorTestHelper.getTestResourceLocator;
import static com.hubspot.jinjava.loader.RelativePathResolver.CURRENT_PATH_CONTEXT_KEY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertTrue;

import com.google.common.io.Resources;
import com.hubspot.jinjava.BaseInterpretingTest;
Expand All @@ -16,7 +16,6 @@
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -27,8 +26,7 @@ public class FromTagTest extends BaseInterpretingTest {
public void setup() {
jinjava.setResourceLocator(
new ResourceLocator() {
private final RelativePathResolver relativePathResolver =
new RelativePathResolver();
private RelativePathResolver relativePathResolver = new RelativePathResolver();

@Override
public String getString(
Expand Down Expand Up @@ -68,27 +66,25 @@ public void itImportsAliasedMacroName() {
}

@Test
public void importedCycleDetected() {
public void importedCycleDected() {
fixture("from-recursion");
assertThat(
assertTrue(
interpreter
.getErrorsCopy()
.stream()
.anyMatch(e -> e.getCategory() == BasicTemplateErrorCategory.FROM_CYCLE_DETECTED)
)
.isTrue();
);
}

@Test
public void importedIndirectCycleDetected() {
public void importedIndirectCycleDected() {
fixture("from-a-to-b");
assertThat(
assertTrue(
interpreter
.getErrorsCopy()
.stream()
.anyMatch(e -> e.getCategory() == BasicTemplateErrorCategory.FROM_CYCLE_DETECTED)
)
.isTrue();
);
}

@Test
Expand Down Expand Up @@ -116,190 +112,6 @@ public void itDefersImport() {
assertThat(spacer.isDeferred()).isTrue();
}

@Test
public void itResolvesNestedRelativeImports() throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"level0.jinja",
"{% from 'level1/nested.jinja' import macro1 %}{{ macro1() }}",
"level1/nested.jinja",
"{% from '../level1/deeper/macro.jinja' import macro2 %}{% macro macro1() %}L1:{{ macro2() }}{% endmacro %}",
"level1/deeper/macro.jinja",
"{% from '../../utils/helper.jinja' import helper %}{% macro macro2() %}L2:{{ helper() }}{% endmacro %}",
"utils/helper.jinja",
"{% macro helper() %}HELPER{% endmacro %}"
)
)
);

interpreter.getContext().getCurrentPathStack().push("level0.jinja", 1, 0);
String result = interpreter.render(interpreter.getResource("level0.jinja"));

assertThat(interpreter.getErrors()).isEmpty();
assertThat(result.trim()).isEqualTo("L1:L2:HELPER");
}

@Test
public void itMaintainsPathStackIntegrity() throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"root.jinja",
"{% from 'simple/macro.jinja' import simple_macro %}{{ simple_macro() }}",
"simple/macro.jinja",
"{% macro simple_macro() %}SIMPLE{% endmacro %}"
)
)
);

interpreter.getContext().getCurrentPathStack().push("root.jinja", 1, 0);
Optional<String> initialTopPath = interpreter
.getContext()
.getCurrentPathStack()
.peek();

interpreter.render(interpreter.getResource("root.jinja"));

assertThat(interpreter.getContext().getCurrentPathStack().peek())
.isEqualTo(initialTopPath);
assertThat(interpreter.getErrors()).isEmpty();
}

@Test
public void itWorksWithIncludeAndFromTogether() throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"mixed-tags.jinja",
"{% from 'macros/test.jinja' import test_macro %}{% include 'includes/content.jinja' %}{{ test_macro() }}",
"macros/test.jinja",
"{% from '../utils/shared.jinja' import shared %}{% macro test_macro() %}MACRO:{{ shared() }}{% endmacro %}",
"includes/content.jinja",
"{% from '../utils/shared.jinja' import shared %}INCLUDE:{{ shared() }}",
"utils/shared.jinja",
"{% macro shared() %}SHARED{% endmacro %}"
)
)
);

interpreter.getContext().getCurrentPathStack().push("mixed-tags.jinja", 1, 0);
String result = interpreter.render(interpreter.getResource("mixed-tags.jinja"));

assertThat(interpreter.getErrors()).isEmpty();
assertThat(result.trim()).contains("INCLUDE:SHARED");
assertThat(result.trim()).contains("MACRO:SHARED");
}

@Test
public void itResolvesUpAndAcrossDirectoryPaths() throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"theme/hubl-modules/navigation.module/module.hubl.html",
"{% from '../../partials/atoms/link/link.hubl.html' import link_macro %}{{ link_macro() }}",
"theme/partials/atoms/link/link.hubl.html",
"{% from '../icons/icons.hubl.html' import icon_macro %}{% macro link_macro() %}LINK:{{ icon_macro() }}{% endmacro %}",
"theme/partials/atoms/icons/icons.hubl.html",
"{% macro icon_macro() %}ICON{% endmacro %}"
)
)
);

interpreter
.getContext()
.getCurrentPathStack()
.push("theme/hubl-modules/navigation.module/module.hubl.html", 1, 0);
String result = interpreter.render(
interpreter.getResource("theme/hubl-modules/navigation.module/module.hubl.html")
);

assertThat(interpreter.getErrors()).isEmpty();
assertThat(result.trim()).isEqualTo("LINK:ICON");
}

@Test
public void itResolvesProjectsAbsolutePathsWithNestedRelativeImports()
throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"@projects/theme-a/modules/header/header.html",
"{% from '../../components/button.html' import render_button %}{{ render_button('primary') }}",
"@projects/theme-a/components/button.html",
"{% from '../utils/icons.html' import get_icon %}{% macro render_button(type) %}{{ type }}-{{ get_icon() }}{% endmacro %}",
"@projects/theme-a/utils/icons.html",
"{% macro get_icon() %}ICON{% endmacro %}"
)
)
);

interpreter
.getContext()
.getCurrentPathStack()
.push("@projects/theme-a/modules/header/header.html", 1, 0);
String result = interpreter.render(
interpreter.getResource("@projects/theme-a/modules/header/header.html")
);

assertThat(interpreter.getErrors()).isEmpty();
assertThat(result.trim()).isEqualTo("primary-ICON");
}

@Test
public void itResolvesHubspotAbsolutePathsWithNestedRelativeImports() throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"@hubspot/modules/forms/contact-form.html",
"{% from '../../shared/validation.html' import validate_field %}{{ validate_field('email') }}",
"@hubspot/shared/validation.html",
"{% from '../helpers/formatters.html' import format_error %}{% macro validate_field(field) %}{{ format_error(field) }}{% endmacro %}",
"@hubspot/helpers/formatters.html",
"{% macro format_error(field) %}ERROR:{{ field }}{% endmacro %}"
)
)
);

interpreter
.getContext()
.getCurrentPathStack()
.push("@hubspot/modules/forms/contact-form.html", 1, 0);
String result = interpreter.render(
interpreter.getResource("@hubspot/modules/forms/contact-form.html")
);

assertThat(interpreter.getErrors()).isEmpty();
assertThat(result.trim()).isEqualTo("ERROR:email");
}

@Test
public void itResolvesMixedAbsoluteAndRelativeImports() throws Exception {
jinjava.setResourceLocator(
getTestResourceLocator(
Map.of(
"@projects/mixed/module.html",
"{% from '@hubspot/shared/globals.html' import global_helper %}{{ global_helper() }}",
"@hubspot/shared/globals.html",
"{% from '../utils/common.html' import format_text %}{% macro global_helper() %}{{ format_text('MIXED') }}{% endmacro %}",
"@hubspot/utils/common.html",
"{% macro format_text(text) %}FORMAT:{{ text }}{% endmacro %}"
)
)
);

interpreter
.getContext()
.getCurrentPathStack()
.push("@projects/mixed/module.html", 1, 0);
String result = interpreter.render(
interpreter.getResource("@projects/mixed/module.html")
);

assertThat(interpreter.getErrors()).isEmpty();
assertThat(result.trim()).isEqualTo("FORMAT:MIXED");
}

private String fixture(String name) {
return interpreter.renderFlat(fixtureText(name));
}
Expand Down
Loading