Skip to content

Commit d292c54

Browse files
committed
fixed utils + added tests for find-nth formatter
1 parent 7cbc2fe commit d292c54

3 files changed

Lines changed: 58 additions & 4 deletions

File tree

core/src/main/java/com/squarespace/template/plugins/CoreFormatters.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public void registerFormatters(SymbolTable<StringView, Formatter> table) {
7878
table.add(new EncodeUriComponentFormatter());
7979
table.add(new FindFirstFormatter());
8080
table.add(new FindLastFormatter());
81+
table.add(new FindNthFormatter());
8182
table.add(new FormatFormatter());
8283
table.add(new GetFormatter());
8384
table.add(new HtmlFormatter());

core/src/main/java/com/squarespace/template/plugins/FindUtils.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ public static JsonNode findNthValidEntry(JsonNode items, Object[] path, JsonNode
3939
}
4040
ArrayNode validEntries = JsonUtils.createArrayNode();
4141
boolean hasLookup = lookup != null;
42-
for (JsonNode element : items) {
43-
JsonNode candidate = hasLookup ? lookup.path(element.asText()) : element;
44-
if (isTruthy(getNodeAtPath(candidate, path))) {
45-
validEntries.add(candidate);
42+
if(hasLookup || path != null){
43+
for (JsonNode element : items) {
44+
JsonNode candidate = hasLookup ? lookup.path(element.asText()) : element;
45+
if (isTruthy(getNodeAtPath(candidate, path))) {
46+
validEntries.add(element);
47+
}
4648
}
49+
} else {
50+
validEntries = (ArrayNode)items;
4751
}
4852
int size = validEntries.size();
4953
if (size == 0) {

core/src/test/java/com/squarespace/template/plugins/CoreFormattersTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import com.squarespace.template.plugins.CoreFormatters.EncodeUriFormatter;
5353
import com.squarespace.template.plugins.CoreFormatters.FindFirstFormatter;
5454
import com.squarespace.template.plugins.CoreFormatters.FindLastFormatter;
55+
import com.squarespace.template.plugins.CoreFormatters.FindNthFormatter;
5556
import com.squarespace.template.plugins.CoreFormatters.HtmlAttrFormatter;
5657
import com.squarespace.template.plugins.CoreFormatters.HtmlFormatter;
5758
import com.squarespace.template.plugins.CoreFormatters.HtmlTagFormatter;
@@ -85,6 +86,7 @@ public class CoreFormattersTest extends UnitTestBase {
8586
private static final Formatter ENCODE_URI_COMPONENT = new EncodeUriComponentFormatter();
8687
private static final Formatter FIND_FIRST = new FindFirstFormatter();
8788
private static final Formatter FIND_LAST = new FindLastFormatter();
89+
private static final Formatter FIND_NTH = new FindNthFormatter();
8890
private static final Formatter HTML = new HtmlFormatter();
8991
private static final Formatter HTMLATTR = new HtmlAttrFormatter();
9092
private static final Formatter HTMLTAG = new HtmlTagFormatter();
@@ -624,6 +626,53 @@ public void testFindLast() throws CodeException {
624626
assertContext(ctx, "b");
625627
}
626628

629+
@Test
630+
public void testFindNth() throws CodeException {
631+
CodeMaker mk = maker();
632+
633+
// index selection
634+
assertFormatter(FIND_NTH, mk.args(" 0"), "[\"a\",\"b\",\"c\"]", "a");
635+
assertFormatter(FIND_NTH, mk.args(" 1"), "[\"a\",\"b\",\"c\"]", "b");
636+
assertFormatter(FIND_NTH, mk.args(" 2"), "[\"a\",\"b\",\"c\"]", "c");
637+
638+
// negative index (counts from end)
639+
assertFormatter(FIND_NTH, mk.args(" -1"), "[\"a\",\"b\",\"c\"]", "c");
640+
assertFormatter(FIND_NTH, mk.args(" -2"), "[\"a\",\"b\",\"c\"]", "b");
641+
642+
// out of bounds
643+
assertFormatter(FIND_NTH, mk.args(" 5"), "[\"a\",\"b\",\"c\"]", "");
644+
assertFormatter(FIND_NTH, mk.args(" -4"), "[\"a\",\"b\",\"c\"]", "");
645+
646+
// edge cases: empty array, non-array, non-integer nth
647+
assertFormatter(FIND_NTH, mk.args(" 0"), "[]", "");
648+
assertFormatter(FIND_NTH, mk.args(" 0"), "\"not-an-array\"", "");
649+
assertFormatter(FIND_NTH, mk.args(" notAnInt"), "[\"a\",\"b\",\"c\"]", "");
650+
651+
// with path filter
652+
assertFormatterRaw(
653+
FIND_NTH, mk.args(" 1 enabled"),
654+
"[{\"id\":\"a\",\"enabled\":true},{\"id\":\"b\",\"enabled\":true},{\"id\":\"c\",\"enabled\":false}]",
655+
JsonUtils.decode("{\"id\":\"b\",\"enabled\":true}")
656+
);
657+
assertFormatter(FIND_NTH, mk.args(" 0 enabled"), "[{\"id\":\"a\",\"enabled\":false},{\"id\":\"b\"}]", "");
658+
659+
// with path filter via template
660+
Context ctx = compiler().newExecutor()
661+
.json("{\"items\": [{\"id\":\"a\",\"enabled\":true},{\"id\":\"b\",\"enabled\":true},{\"id\":\"c\",\"enabled\":false}]}")
662+
.template("{.var @item items|find-nth 1 enabled}{@item.id}")
663+
.safeExecution(true)
664+
.execute();
665+
assertContext(ctx, "b");
666+
667+
// with lookup + path filter via template
668+
ctx = compiler().newExecutor()
669+
.json("{\"keys\": [\"a\", \"b\", \"c\"], \"map\": {\"a\": {\"enabled\": true}, \"b\": {\"enabled\": true}, \"c\": {\"enabled\": false}}}")
670+
.template("{keys|find-nth 1 map enabled}")
671+
.safeExecution(true)
672+
.execute();
673+
assertContext(ctx, "b");
674+
}
675+
627676
@Test
628677
public void testLineBreaks() throws CodeException {
629678
runner.exec("f-line-breaks-%N.html");

0 commit comments

Comments
 (0)