|
52 | 52 | import com.squarespace.template.plugins.CoreFormatters.EncodeUriFormatter; |
53 | 53 | import com.squarespace.template.plugins.CoreFormatters.FindFirstFormatter; |
54 | 54 | import com.squarespace.template.plugins.CoreFormatters.FindLastFormatter; |
| 55 | +import com.squarespace.template.plugins.CoreFormatters.FindNthFormatter; |
55 | 56 | import com.squarespace.template.plugins.CoreFormatters.HtmlAttrFormatter; |
56 | 57 | import com.squarespace.template.plugins.CoreFormatters.HtmlFormatter; |
57 | 58 | import com.squarespace.template.plugins.CoreFormatters.HtmlTagFormatter; |
@@ -85,6 +86,7 @@ public class CoreFormattersTest extends UnitTestBase { |
85 | 86 | private static final Formatter ENCODE_URI_COMPONENT = new EncodeUriComponentFormatter(); |
86 | 87 | private static final Formatter FIND_FIRST = new FindFirstFormatter(); |
87 | 88 | private static final Formatter FIND_LAST = new FindLastFormatter(); |
| 89 | + private static final Formatter FIND_NTH = new FindNthFormatter(); |
88 | 90 | private static final Formatter HTML = new HtmlFormatter(); |
89 | 91 | private static final Formatter HTMLATTR = new HtmlAttrFormatter(); |
90 | 92 | private static final Formatter HTMLTAG = new HtmlTagFormatter(); |
@@ -624,6 +626,53 @@ public void testFindLast() throws CodeException { |
624 | 626 | assertContext(ctx, "b"); |
625 | 627 | } |
626 | 628 |
|
| 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 | + |
627 | 676 | @Test |
628 | 677 | public void testLineBreaks() throws CodeException { |
629 | 678 | runner.exec("f-line-breaks-%N.html"); |
|
0 commit comments