diff --git a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTag.java b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTag.java index 0b45a0a59..6514a82a0 100644 --- a/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTag.java +++ b/src/main/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTag.java @@ -9,16 +9,18 @@ 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.loader.RelativePathResolver; +import com.hubspot.jinjava.lib.tag.eager.importing.EagerImportingStrategyFactory; import com.hubspot.jinjava.tree.Node; import com.hubspot.jinjava.tree.parse.TagToken; import com.hubspot.jinjava.util.EagerReconstructionUtils; +import com.hubspot.jinjava.util.PrefixToPreserveState; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; @Beta public class EagerFromTag extends EagerStateChangingTag { @@ -33,6 +35,9 @@ public EagerFromTag(FromTag fromTag) { @Override public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter) { + String initialPathSetter = EagerImportingStrategyFactory.getSetTagForCurrentPath( + interpreter + ); List helper = FromTag.getHelpers(tagToken); Map imports = FromTag.getImportMap(helper); Optional maybeTemplateFile; @@ -55,10 +60,17 @@ public String getEagerTagImage(TagToken tagToken, JinjavaInterpreter interpreter interpreter.getContext().addGlobalMacro(deferredMacro); }); return ( - EagerReconstructionUtils.buildBlockOrInlineSetTag( - RelativePathResolver.CURRENT_PATH_CONTEXT_KEY, - interpreter.getContext().get(RelativePathResolver.CURRENT_PATH_CONTEXT_KEY), - interpreter + initialPathSetter + + new PrefixToPreserveState( + EagerReconstructionUtils.handleDeferredTokenAndReconstructReferences( + interpreter, + DeferredToken + .builderFromToken(tagToken) + .addUsedDeferredWords(Stream.of(helper.get(0))) + .addUsedDeferredWords(imports.keySet()) + .addSetDeferredWords(imports.values()) + .build() + ) ) + tagToken.getImage() ); diff --git a/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTagTest.java b/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTagTest.java index 5bf876ed6..54d288f1d 100644 --- a/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTagTest.java +++ b/src/test/java/com/hubspot/jinjava/lib/tag/eager/EagerFromTagTest.java @@ -75,9 +75,37 @@ public void teardown() { public void itDefersWhenPathIsDeferred() { String input = "{% from deferred import foo %}"; String output = interpreter.render(input); - assertThat(output).isEqualTo("{% set current_path = null %}" + input); + assertThat(output).isEqualTo("{% set current_path = '' %}" + input); assertThat(interpreter.getContext().getGlobalMacro("foo")).isNotNull(); assertThat(interpreter.getContext().getGlobalMacro("foo").isDeferred()).isTrue(); + assertThat(interpreter.getContext().getDeferredTokens()) + .isNotEmpty() + .anySatisfy(deferredToken -> { + assertThat(deferredToken.getToken().getImage()) + .isEqualTo("{% from deferred import foo %}"); + assertThat(deferredToken.getSetDeferredWords()).containsExactly("foo"); + assertThat(deferredToken.getUsedDeferredWords()) + .containsExactlyInAnyOrder("deferred", "foo"); + }); + } + + @Test + public void itDefersWhenPathIsDeferredWithAlias() { + String input = "{% from deferred import foo as new_foo %}"; + String output = interpreter.render(input); + assertThat(output).isEqualTo("{% set current_path = '' %}" + input); + assertThat(interpreter.getContext().getGlobalMacro("new_foo")).isNotNull(); + assertThat(interpreter.getContext().getGlobalMacro("new_foo").isDeferred()).isTrue(); + assertThat(interpreter.getContext().getDeferredTokens()) + .isNotEmpty() + .anySatisfy(deferredToken -> { + assertThat(deferredToken.getToken().getImage()) + .isEqualTo("{% from deferred import foo as new_foo %}"); + assertThat(deferredToken.getSetDeferredWords()).containsExactly("new_foo"); + assertThat(deferredToken.getUsedDeferredWords()) + .containsExactlyInAnyOrder("deferred", "foo"); + }); + assertThat(interpreter.getContext().get("new_foo")).isInstanceOf(DeferredValue.class); } @Test