Skip to content

Commit

Permalink
find first valid deferred words
Browse files Browse the repository at this point in the history
  • Loading branch information
jboulter committed Apr 15, 2024
1 parent 61452e4 commit 1f88ba3
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/main/java/com/hubspot/jinjava/lib/tag/eager/DeferredToken.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hubspot.jinjava.lib.tag.eager;

import com.google.common.annotations.Beta;
import com.google.common.base.Strings;
import com.hubspot.jinjava.interpret.CallStack;
import com.hubspot.jinjava.interpret.Context;
import com.hubspot.jinjava.interpret.DeferredLazyReference;
Expand All @@ -13,9 +14,11 @@
import com.hubspot.jinjava.tree.parse.TokenScannerSymbols;
import com.hubspot.jinjava.util.EagerExpressionResolver;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -40,7 +43,8 @@ public DeferredToken build() {
token,
usedDeferredWords != null
? usedDeferredWords
.map(prop -> prop.split("\\.", 2)[0])
.map(DeferredToken::splitToken)
.map(DeferredToken::getFirstNonEmptyToken)
.distinct()
.filter(word ->
interpreter == null ||
Expand All @@ -50,7 +54,8 @@ public DeferredToken build() {
: Collections.emptySet(),
setDeferredWords != null
? setDeferredWords
.map(prop -> prop.split("\\.", 2)[0])
.map(DeferredToken::splitToken)
.map(DeferredToken::getFirstNonEmptyToken)
.collect(Collectors.toSet())
: Collections.emptySet(),
acquireImportResourcePath(),
Expand Down Expand Up @@ -413,10 +418,19 @@ private static CallStack acquireMacroStack() {
.orElse(null);
}

private static String getFirstNonEmptyToken(List<String> strings) {
return Strings.isNullOrEmpty(strings.get(0)) ? strings.get(1) : strings.get(0);
}

public static List<String> splitToken(String token) {
return Arrays.asList(token.split("\\.", 2));
}

public static Set<String> getBases(Set<String> original) {
return original
.stream()
.map(prop -> prop.split("\\.", 2)[0])
.map(DeferredToken::splitToken)
.map(prop -> prop.get(0))
.collect(Collectors.toSet());
}
}
21 changes: 21 additions & 0 deletions src/test/java/com/hubspot/jinjava/EagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,27 @@ public void itEvaluatesNonEagerSet() {
.contains("deferred");
}

@Test
public void itDefersArrayAccess() {
expectedTemplateInterpreter.assertExpectedOutput("evaluates-non-eager-set");
assertThat(
localContext
.getDeferredTokens()
.stream()
.flatMap(deferredToken -> deferredToken.getSetDeferredWords().stream())
.collect(Collectors.toSet())
)
.isEmpty();
assertThat(
localContext
.getDeferredTokens()
.stream()
.flatMap(deferredToken -> deferredToken.getUsedDeferredWords().stream())
.collect(Collectors.toSet())
)
.contains("deferred");
}

@Test
public void itDefersOnImmutableMode() {
expectedTemplateInterpreter.assertExpectedOutput("defers-on-immutable-mode");
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/com/hubspot/jinjava/util/DeferredValueUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,22 @@ public void itDefersUsedWordsInDeferredTokens() {
assertThat(context.containsKey("int")).isFalse();
}

@Test
public void itFindsFirstValidDeferredWords() {
DeferredToken deferredToken = DeferredToken
.builderFromToken(
new ExpressionToken("{{ blah }}", 1, 1, new DefaultTokenScannerSymbols())
)
.addUsedDeferredWords(ImmutableSet.of("deferred", ".attribute1"))
.addSetDeferredWords(ImmutableSet.of("deferred", ".attribute2"))
.build();

assertThat(deferredToken.getUsedDeferredWords())
.isEqualTo(ImmutableSet.of("deferred", "attribute1"));
assertThat(deferredToken.getSetDeferredWords())
.isEqualTo(ImmutableSet.of("deferred", "attribute2"));
}

private Context getContext(List<? extends Node> nodes) {
return getContext(nodes, Optional.empty());
}
Expand Down

0 comments on commit 1f88ba3

Please sign in to comment.