comparison tests/test-command-template.t @ 38434:70f551a3f52e

tests: extract test-template-functions.t from test-command-template.t I decided to not split filters and functions into two test files since we sometimes reimplement a filter as a function.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 16 Jun 2018 13:17:11 +0900
parents ddce7bdf7f3c
children da4508cdef37
comparison
equal deleted inserted replaced
38433:ddce7bdf7f3c 38434:70f551a3f52e
927 p2node--debug: 0000000000000000000000000000000000000000 927 p2node--debug: 0000000000000000000000000000000000000000
928 p2node--debug: 0000000000000000000000000000000000000000 928 p2node--debug: 0000000000000000000000000000000000000000
929 p2node--debug: 0000000000000000000000000000000000000000 929 p2node--debug: 0000000000000000000000000000000000000000
930 p2node--debug: 0000000000000000000000000000000000000000 930 p2node--debug: 0000000000000000000000000000000000000000
931 931
932 Filters work:
933
934 $ hg log --template '{author|domain}\n'
935
936 hostname
937
938
939
940
941 place
942 place
943 hostname
944
945 $ hg log --template '{author|person}\n'
946 test
947 User Name
948 person
949 person
950 person
951 person
952 other
953 A. N. Other
954 User Name
955
956 $ hg log --template '{author|user}\n'
957 test
958 user
959 person
960 person
961 person
962 person
963 other
964 other
965 user
966
967 $ hg log --template '{date|date}\n'
968 Wed Jan 01 10:01:00 2020 +0000
969 Mon Jan 12 13:46:40 1970 +0000
970 Sun Jan 18 08:40:01 1970 +0000
971 Sun Jan 18 08:40:00 1970 +0000
972 Sat Jan 17 04:53:20 1970 +0000
973 Fri Jan 16 01:06:40 1970 +0000
974 Wed Jan 14 21:20:00 1970 +0000
975 Tue Jan 13 17:33:20 1970 +0000
976 Mon Jan 12 13:46:40 1970 +0000
977
978 $ hg log --template '{date|isodate}\n'
979 2020-01-01 10:01 +0000
980 1970-01-12 13:46 +0000
981 1970-01-18 08:40 +0000
982 1970-01-18 08:40 +0000
983 1970-01-17 04:53 +0000
984 1970-01-16 01:06 +0000
985 1970-01-14 21:20 +0000
986 1970-01-13 17:33 +0000
987 1970-01-12 13:46 +0000
988
989 $ hg log --template '{date|isodatesec}\n'
990 2020-01-01 10:01:00 +0000
991 1970-01-12 13:46:40 +0000
992 1970-01-18 08:40:01 +0000
993 1970-01-18 08:40:00 +0000
994 1970-01-17 04:53:20 +0000
995 1970-01-16 01:06:40 +0000
996 1970-01-14 21:20:00 +0000
997 1970-01-13 17:33:20 +0000
998 1970-01-12 13:46:40 +0000
999
1000 $ hg log --template '{date|rfc822date}\n'
1001 Wed, 01 Jan 2020 10:01:00 +0000
1002 Mon, 12 Jan 1970 13:46:40 +0000
1003 Sun, 18 Jan 1970 08:40:01 +0000
1004 Sun, 18 Jan 1970 08:40:00 +0000
1005 Sat, 17 Jan 1970 04:53:20 +0000
1006 Fri, 16 Jan 1970 01:06:40 +0000
1007 Wed, 14 Jan 1970 21:20:00 +0000
1008 Tue, 13 Jan 1970 17:33:20 +0000
1009 Mon, 12 Jan 1970 13:46:40 +0000
1010
1011 $ hg log --template '{desc|firstline}\n'
1012 third
1013 second
1014 merge
1015 new head
1016 new branch
1017 no user, no domain
1018 no person
1019 other 1
1020 line 1
1021
1022 $ hg log --template '{node|short}\n'
1023 95c24699272e
1024 29114dbae42b
1025 d41e714fe50d
1026 13207e5a10d9
1027 bbe44766e73d
1028 10e46f2dcbf4
1029 97054abb4ab8
1030 b608e9d1a3f0
1031 1e4e1b8f71e0
1032
1033 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1034 <changeset author="test"/>
1035 <changeset author="User Name &lt;user@hostname&gt;"/>
1036 <changeset author="person"/>
1037 <changeset author="person"/>
1038 <changeset author="person"/>
1039 <changeset author="person"/>
1040 <changeset author="other@place"/>
1041 <changeset author="A. N. Other &lt;other@place&gt;"/>
1042 <changeset author="User Name &lt;user@hostname&gt;"/>
1043
1044 $ hg log --template '{rev}: {children}\n'
1045 8:
1046 7: 8:95c24699272e
1047 6:
1048 5: 6:d41e714fe50d
1049 4: 6:d41e714fe50d
1050 3: 4:bbe44766e73d 5:13207e5a10d9
1051 2: 3:10e46f2dcbf4
1052 1: 2:97054abb4ab8
1053 0: 1:b608e9d1a3f0
1054
1055 Formatnode filter works:
1056
1057 $ hg -q log -r 0 --template '{node|formatnode}\n'
1058 1e4e1b8f71e0
1059
1060 $ hg log -r 0 --template '{node|formatnode}\n'
1061 1e4e1b8f71e0
1062
1063 $ hg -v log -r 0 --template '{node|formatnode}\n'
1064 1e4e1b8f71e0
1065
1066 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1067 1e4e1b8f71e05681d422154f5421e385fec3454f
1068
1069 Age filter:
1070
1071 $ hg init unstable-hash
1072 $ cd unstable-hash
1073 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1074
1075 >>> from __future__ import absolute_import
1076 >>> import datetime
1077 >>> fp = open('a', 'wb')
1078 >>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
1079 >>> fp.write(b'%d-%d-%d 00:00' % (n.year, n.month, n.day)) and None
1080 >>> fp.close()
1081 $ hg add a
1082 $ hg commit -m future -d "`cat a`"
1083
1084 $ hg log -l1 --template '{date|age}\n'
1085 7 years from now
1086
1087 $ cd ..
1088 $ rm -rf unstable-hash
1089
1090 Filename filters:
1091
1092 $ hg debugtemplate '{"foo/bar"|basename}|{"foo/"|basename}|{"foo"|basename}|\n'
1093 bar||foo|
1094 $ hg debugtemplate '{"foo/bar"|dirname}|{"foo/"|dirname}|{"foo"|dirname}|\n'
1095 foo|foo||
1096 $ hg debugtemplate '{"foo/bar"|stripdir}|{"foo/"|stripdir}|{"foo"|stripdir}|\n'
1097 foo|foo|foo|
1098
1099 Add a dummy commit to make up for the instability of the above: 932 Add a dummy commit to make up for the instability of the above:
1100 933
1101 $ echo a > a 934 $ echo a > a
1102 $ hg add a 935 $ hg add a
1103 $ hg ci -m future 936 $ hg ci -m future
1104
1105 Count filter:
1106
1107 $ hg log -l1 --template '{node|count} {node|short|count}\n'
1108 40 12
1109
1110 $ hg log -l1 --template '{revset("null^")|count} {revset(".")|count} {revset("0::3")|count}\n'
1111 0 1 4
1112
1113 $ hg log -G --template '{rev}: children: {children|count}, \
1114 > tags: {tags|count}, file_adds: {file_adds|count}, \
1115 > ancestors: {revset("ancestors(%s)", rev)|count}'
1116 @ 9: children: 0, tags: 1, file_adds: 1, ancestors: 3
1117 |
1118 o 8: children: 1, tags: 0, file_adds: 2, ancestors: 2
1119 |
1120 o 7: children: 1, tags: 0, file_adds: 1, ancestors: 1
1121
1122 o 6: children: 0, tags: 0, file_adds: 0, ancestors: 7
1123 |\
1124 | o 5: children: 1, tags: 0, file_adds: 1, ancestors: 5
1125 | |
1126 o | 4: children: 1, tags: 0, file_adds: 0, ancestors: 5
1127 |/
1128 o 3: children: 2, tags: 0, file_adds: 0, ancestors: 4
1129 |
1130 o 2: children: 1, tags: 0, file_adds: 1, ancestors: 3
1131 |
1132 o 1: children: 1, tags: 0, file_adds: 1, ancestors: 2
1133 |
1134 o 0: children: 1, tags: 0, file_adds: 1, ancestors: 1
1135
1136
1137 $ hg log -l1 -T '{termwidth|count}\n'
1138 hg: parse error: not countable
1139 (template filter 'count' is not compatible with keyword 'termwidth')
1140 [255]
1141
1142 Upper/lower filters:
1143
1144 $ hg log -r0 --template '{branch|upper}\n'
1145 DEFAULT
1146 $ hg log -r0 --template '{author|lower}\n'
1147 user name <user@hostname>
1148 $ hg log -r0 --template '{date|upper}\n'
1149 1000000.00
1150 937
1151 Add a commit that does all possible modifications at once 938 Add a commit that does all possible modifications at once
1152 939
1153 $ echo modify >> third 940 $ echo modify >> third
1154 $ touch b 941 $ touch b
1264 1051
1265 $ hg tip --template '{foo()}\n' 1052 $ hg tip --template '{foo()}\n'
1266 hg: parse error: unknown function 'foo' 1053 hg: parse error: unknown function 'foo'
1267 [255] 1054 [255]
1268 1055
1269 Pass generator object created by template function to filter
1270
1271 $ hg log -l 1 --template '{if(author, author)|user}\n'
1272 test
1273
1274 Test index keyword: 1056 Test index keyword:
1275 1057
1276 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n' 1058 $ hg log -l 2 -T '{index + 10}{files % " {index}:{file}"}\n'
1277 10 0:a 1:b 2:fifth 3:fourth 4:third 1059 10 0:a 1:b 2:fifth 3:fourth 4:third
1278 11 0:a 1060 11 0:a
1279 1061
1280 $ hg branches -T '{index} {branch}\n' 1062 $ hg branches -T '{index} {branch}\n'
1281 0 default 1063 0 default
1282 1 foo 1064 1 foo
1283
1284 Test diff function:
1285
1286 $ hg diff -c 8
1287 diff -r 29114dbae42b -r 95c24699272e fourth
1288 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1289 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1290 @@ -0,0 +1,1 @@
1291 +second
1292 diff -r 29114dbae42b -r 95c24699272e second
1293 --- a/second Mon Jan 12 13:46:40 1970 +0000
1294 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1295 @@ -1,1 +0,0 @@
1296 -second
1297 diff -r 29114dbae42b -r 95c24699272e third
1298 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1299 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1300 @@ -0,0 +1,1 @@
1301 +third
1302
1303 $ hg log -r 8 -T "{diff()}"
1304 diff -r 29114dbae42b -r 95c24699272e fourth
1305 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1306 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1307 @@ -0,0 +1,1 @@
1308 +second
1309 diff -r 29114dbae42b -r 95c24699272e second
1310 --- a/second Mon Jan 12 13:46:40 1970 +0000
1311 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1312 @@ -1,1 +0,0 @@
1313 -second
1314 diff -r 29114dbae42b -r 95c24699272e third
1315 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1316 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1317 @@ -0,0 +1,1 @@
1318 +third
1319
1320 $ hg log -r 8 -T "{diff('glob:f*')}"
1321 diff -r 29114dbae42b -r 95c24699272e fourth
1322 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1323 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1324 @@ -0,0 +1,1 @@
1325 +second
1326
1327 $ hg log -r 8 -T "{diff('', 'glob:f*')}"
1328 diff -r 29114dbae42b -r 95c24699272e second
1329 --- a/second Mon Jan 12 13:46:40 1970 +0000
1330 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1331 @@ -1,1 +0,0 @@
1332 -second
1333 diff -r 29114dbae42b -r 95c24699272e third
1334 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1335 +++ b/third Wed Jan 01 10:01:00 2020 +0000
1336 @@ -0,0 +1,1 @@
1337 +third
1338
1339 $ hg log -r 8 -T "{diff('FOURTH'|lower)}"
1340 diff -r 29114dbae42b -r 95c24699272e fourth
1341 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1342 +++ b/fourth Wed Jan 01 10:01:00 2020 +0000
1343 @@ -0,0 +1,1 @@
1344 +second
1345 1065
1346 ui verbosity: 1066 ui verbosity:
1347 1067
1348 $ hg log -l1 -T '{verbosity}\n' 1068 $ hg log -l1 -T '{verbosity}\n'
1349 1069
1543 o 1: t1+0,0 1263 o 1: t1+0,0
1544 | 1264 |
1545 o 0: null+1,1 1265 o 0: null+1,1
1546 1266
1547 1267
1548 $ hg log -G --template "{rev}: {latesttag('re:^t[13]$') % '{tag}, C: {changes}, D: {distance}'}\n"
1549 @ 11: t3, C: 9, D: 8
1550 |
1551 o 10: t3, C: 8, D: 7
1552 |
1553 o 9: t3, C: 7, D: 6
1554 |
1555 o 8: t3, C: 6, D: 5
1556 |
1557 o 7: t3, C: 5, D: 4
1558 |
1559 o 6: t3, C: 4, D: 3
1560 |
1561 o 5: t3, C: 3, D: 2
1562 |\
1563 | o 4: t3, C: 1, D: 1
1564 | |
1565 | o 3: t3, C: 0, D: 0
1566 | |
1567 o | 2: t1, C: 1, D: 1
1568 |/
1569 o 1: t1, C: 0, D: 0
1570 |
1571 o 0: null, C: 1, D: 1
1572
1573
1574 $ cd .. 1268 $ cd ..
1575 1269
1576 Test new-style inline templating: 1270 Test new-style inline templating:
1577 1271
1578 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n' 1272 $ hg log -R latesttag -r tip --template 'modified files: {file_mods % " {file}\n"}\n'
1609 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}' 1303 $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}'
1610 0:ce3cec86e6c2 1304 0:ce3cec86e6c2
1611 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}' 1305 $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}'
1612 9:fbc7cd862e9c 1306 9:fbc7cd862e9c
1613 1307
1614 Test manifest/get() can be join()-ed as string, though it's silly:
1615
1616 $ hg log -R latesttag -r tip -T '{join(manifest, ".")}\n'
1617 1.1.:.2.b.c.6.e.9.0.0.6.c.e.2
1618 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), ".")}\n'
1619 d.e.f.a.u.l.t
1620
1621 Test join() over string
1622
1623 $ hg log -R latesttag -r tip -T '{join(rev|stringify, ".")}\n'
1624 1.1
1625
1626 Test join() over uniterable
1627
1628 $ hg log -R latesttag -r tip -T '{join(rev, "")}\n'
1629 hg: parse error: 11 is not iterable
1630 [255]
1631
1632 Test min/max of integers
1633
1634 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
1635 9
1636 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
1637 10
1638
1639 Test min/max over map operation:
1640
1641 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
1642 at3
1643 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
1644 t3
1645
1646 Test min/max of strings:
1647
1648 $ hg log -R latesttag -l1 -T '{min(desc)}\n'
1649 3
1650 $ hg log -R latesttag -l1 -T '{max(desc)}\n'
1651 t
1652
1653 Test min/max of non-iterable:
1654
1655 $ hg debugtemplate '{min(1)}'
1656 hg: parse error: 1 is not iterable
1657 (min first argument should be an iterable)
1658 [255]
1659 $ hg debugtemplate '{max(2)}'
1660 hg: parse error: 2 is not iterable
1661 (max first argument should be an iterable)
1662 [255]
1663
1664 $ hg log -R latesttag -l1 -T '{min(date)}'
1665 hg: parse error: date is not iterable
1666 (min first argument should be an iterable)
1667 [255]
1668 $ hg log -R latesttag -l1 -T '{max(date)}'
1669 hg: parse error: date is not iterable
1670 (max first argument should be an iterable)
1671 [255]
1672
1673 Test min/max of empty sequence:
1674
1675 $ hg debugtemplate '{min("")}'
1676 hg: parse error: empty string
1677 (min first argument should be an iterable)
1678 [255]
1679 $ hg debugtemplate '{max("")}'
1680 hg: parse error: empty string
1681 (max first argument should be an iterable)
1682 [255]
1683 $ hg debugtemplate '{min(dict())}'
1684 hg: parse error: empty sequence
1685 (min first argument should be an iterable)
1686 [255]
1687 $ hg debugtemplate '{max(dict())}'
1688 hg: parse error: empty sequence
1689 (max first argument should be an iterable)
1690 [255]
1691 $ hg debugtemplate '{min(dict() % "")}'
1692 hg: parse error: empty sequence
1693 (min first argument should be an iterable)
1694 [255]
1695 $ hg debugtemplate '{max(dict() % "")}'
1696 hg: parse error: empty sequence
1697 (max first argument should be an iterable)
1698 [255]
1699
1700 Test min/max of if() result
1701
1702 $ cd latesttag
1703 $ hg log -l1 -T '{min(if(true, revset("9:10"), ""))}\n'
1704 9
1705 $ hg log -l1 -T '{max(if(false, "", revset("9:10")))}\n'
1706 10
1707 $ hg log -l1 -T '{min(ifcontains("a", "aa", revset("9:10"), ""))}\n'
1708 9
1709 $ hg log -l1 -T '{max(ifcontains("a", "bb", "", revset("9:10")))}\n'
1710 10
1711 $ hg log -l1 -T '{min(ifeq(0, 0, revset("9:10"), ""))}\n'
1712 9
1713 $ hg log -l1 -T '{max(ifeq(0, 1, "", revset("9:10")))}\n'
1714 10
1715 $ cd ..
1716
1717 Test laziness of if() then/else clause
1718
1719 $ hg debugtemplate '{count(0)}'
1720 hg: parse error: not countable
1721 (incompatible use of template filter 'count')
1722 [255]
1723 $ hg debugtemplate '{if(true, "", count(0))}'
1724 $ hg debugtemplate '{if(false, count(0), "")}'
1725 $ hg debugtemplate '{ifcontains("a", "aa", "", count(0))}'
1726 $ hg debugtemplate '{ifcontains("a", "bb", count(0), "")}'
1727 $ hg debugtemplate '{ifeq(0, 0, "", count(0))}'
1728 $ hg debugtemplate '{ifeq(0, 1, count(0), "")}'
1729
1730 Test dot operator precedence: 1308 Test dot operator precedence:
1731 1309
1732 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n' 1310 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
1733 (template 1311 (template
1734 (| 1312 (|
1777 hg: parse error: 'test' is not a dictionary 1355 hg: parse error: 'test' is not a dictionary
1778 (keyword 'author' does not support member operation) 1356 (keyword 'author' does not support member operation)
1779 [255] 1357 [255]
1780 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n' 1358 $ hg log -R latesttag -l1 -T '{min("abc").invalid}\n'
1781 hg: parse error: 'a' is not a dictionary 1359 hg: parse error: 'a' is not a dictionary
1782 [255]
1783
1784 Test the sub function of templating for expansion:
1785
1786 $ hg log -R latesttag -r 10 --template '{sub("[0-9]", "x", "{rev}")}\n'
1787 xx
1788
1789 $ hg log -R latesttag -r 10 -T '{sub("[", "x", rev)}\n'
1790 hg: parse error: sub got an invalid pattern: [
1791 [255]
1792 $ hg log -R latesttag -r 10 -T '{sub("[0-9]", r"\1", rev)}\n'
1793 hg: parse error: sub got an invalid replacement: \1
1794 [255]
1795
1796 Test the strip function with chars specified:
1797
1798 $ hg log -R latesttag --template '{desc}\n'
1799 at3
1800 t5
1801 t4
1802 t3
1803 t2
1804 t1
1805 merge
1806 h2e
1807 h2d
1808 h1c
1809 b
1810 a
1811
1812 $ hg log -R latesttag --template '{strip(desc, "te")}\n'
1813 at3
1814 5
1815 4
1816 3
1817 2
1818 1
1819 merg
1820 h2
1821 h2d
1822 h1c
1823 b
1824 a
1825
1826 Test date format:
1827
1828 $ hg log -R latesttag --template 'date: {date(date, "%y %m %d %S %z")}\n'
1829 date: 70 01 01 10 +0000
1830 date: 70 01 01 09 +0000
1831 date: 70 01 01 04 +0000
1832 date: 70 01 01 08 +0000
1833 date: 70 01 01 07 +0000
1834 date: 70 01 01 06 +0000
1835 date: 70 01 01 05 +0100
1836 date: 70 01 01 04 +0000
1837 date: 70 01 01 03 +0000
1838 date: 70 01 01 02 +0000
1839 date: 70 01 01 01 +0000
1840 date: 70 01 01 00 +0000
1841
1842 Test invalid date:
1843
1844 $ hg log -R latesttag -T '{date(rev)}\n'
1845 hg: parse error: date expects a date information
1846 [255] 1360 [255]
1847 1361
1848 Test integer literal: 1362 Test integer literal:
1849 1363
1850 $ hg debugtemplate -v '{(0)}\n' 1364 $ hg debugtemplate -v '{(0)}\n'
2232 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}' 1746 $ hg log --color=always -l 1 --template '{label(branch, "text\n")}'
2233 \x1b[0;31mtext\x1b[0m (esc) 1747 \x1b[0;31mtext\x1b[0m (esc)
2234 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}' 1748 $ hg log --color=always -l 1 --template '{label("text.{rev}", "text\n")}'
2235 \x1b[0;32mtext\x1b[0m (esc) 1749 \x1b[0;32mtext\x1b[0m (esc)
2236 1750
2237 color effect can be specified without quoting: 1751 Just one more commit:
2238
2239 $ hg log --color=always -l 1 --template '{label(red, "text\n")}'
2240 \x1b[0;31mtext\x1b[0m (esc)
2241
2242 color effects can be nested (issue5413)
2243
2244 $ hg debugtemplate --color=always \
2245 > '{label(red, "red{label(magenta, "ma{label(cyan, "cyan")}{label(yellow, "yellow")}genta")}")}\n'
2246 \x1b[0;31mred\x1b[0;35mma\x1b[0;36mcyan\x1b[0m\x1b[0;31m\x1b[0;35m\x1b[0;33myellow\x1b[0m\x1b[0;31m\x1b[0;35mgenta\x1b[0m (esc)
2247
2248 pad() should interact well with color codes (issue5416)
2249
2250 $ hg debugtemplate --color=always \
2251 > '{pad(label(red, "red"), 5, label(cyan, "-"))}\n'
2252 \x1b[0;31mred\x1b[0m\x1b[0;36m-\x1b[0m\x1b[0;36m-\x1b[0m (esc)
2253
2254 label should be no-op if color is disabled:
2255
2256 $ hg log --color=never -l 1 --template '{label(red, "text\n")}'
2257 text
2258 $ hg log --config extensions.color=! -l 1 --template '{label(red, "text\n")}'
2259 text
2260
2261 Test branches inside if statement:
2262
2263 $ hg log -r 0 --template '{if(branches, "yes", "no")}\n'
2264 no
2265
2266 Test dict constructor:
2267
2268 $ hg log -r 0 -T '{dict(y=node|short, x=rev)}\n'
2269 y=f7769ec2ab97 x=0
2270 $ hg log -r 0 -T '{dict(x=rev, y=node|short) % "{key}={value}\n"}'
2271 x=0
2272 y=f7769ec2ab97
2273 $ hg log -r 0 -T '{dict(x=rev, y=node|short)|json}\n'
2274 {"x": 0, "y": "f7769ec2ab97"}
2275 $ hg log -r 0 -T '{dict()|json}\n'
2276 {}
2277
2278 $ hg log -r 0 -T '{dict(rev, node=node|short)}\n'
2279 rev=0 node=f7769ec2ab97
2280 $ hg log -r 0 -T '{dict(rev, node|short)}\n'
2281 rev=0 node=f7769ec2ab97
2282
2283 $ hg log -r 0 -T '{dict(rev, rev=rev)}\n'
2284 hg: parse error: duplicated dict key 'rev' inferred
2285 [255]
2286 $ hg log -r 0 -T '{dict(node, node|short)}\n'
2287 hg: parse error: duplicated dict key 'node' inferred
2288 [255]
2289 $ hg log -r 0 -T '{dict(1 + 2)}'
2290 hg: parse error: dict key cannot be inferred
2291 [255]
2292
2293 $ hg log -r 0 -T '{dict(x=rev, x=node)}'
2294 hg: parse error: dict got multiple values for keyword argument 'x'
2295 [255]
2296
2297 Test get function:
2298
2299 $ hg log -r 0 --template '{get(extras, "branch")}\n'
2300 default
2301 $ hg log -r 0 --template '{get(extras, "br{"anch"}")}\n'
2302 default
2303 $ hg log -r 0 --template '{get(files, "should_fail")}\n'
2304 hg: parse error: not a dictionary
2305 (get() expects a dict as first argument)
2306 [255]
2307
2308 Test json filter applied to wrapped object:
2309
2310 $ hg log -r0 -T '{files|json}\n'
2311 ["a"]
2312 $ hg log -r0 -T '{extras|json}\n'
2313 {"branch": "default"}
2314 $ hg log -r0 -T '{date|json}\n'
2315 [0, 0]
2316
2317 Test json filter applied to map result:
2318
2319 $ hg log -r0 -T '{json(extras % "{key}")}\n'
2320 ["branch"]
2321
2322 Test localdate(date, tz) function:
2323
2324 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
2325 1970-01-01 09:00 +0900
2326 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "UTC")|isodate}\n'
2327 1970-01-01 00:00 +0000
2328 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "blahUTC")|isodate}\n'
2329 hg: parse error: localdate expects a timezone
2330 [255]
2331 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "+0200")|isodate}\n'
2332 1970-01-01 02:00 +0200
2333 $ TZ=JST-09 hg log -r0 -T '{localdate(date, "0")|isodate}\n'
2334 1970-01-01 00:00 +0000
2335 $ TZ=JST-09 hg log -r0 -T '{localdate(date, 0)|isodate}\n'
2336 1970-01-01 00:00 +0000
2337 $ hg log -r0 -T '{localdate(date, "invalid")|isodate}\n'
2338 hg: parse error: localdate expects a timezone
2339 [255]
2340 $ hg log -r0 -T '{localdate(date, date)|isodate}\n'
2341 hg: parse error: localdate expects a timezone
2342 [255]
2343
2344 Test shortest(node) function:
2345 1752
2346 $ echo b > b 1753 $ echo b > b
2347 $ hg ci -qAm b 1754 $ hg ci -qAm b
2348 $ hg log --template '{shortest(node)}\n'
2349 e777
2350 bcc7
2351 f776
2352 $ hg log --template '{shortest(node, 10)}\n'
2353 e777603221
2354 bcc7ff960b
2355 f7769ec2ab
2356 $ hg log --template '{node|shortest}\n' -l1
2357 e777
2358
2359 $ hg log -r 0 -T '{shortest(node, "1{"0"}")}\n'
2360 f7769ec2ab
2361 $ hg log -r 0 -T '{shortest(node, "not an int")}\n'
2362 hg: parse error: shortest() expects an integer minlength
2363 [255]
2364
2365 $ hg log -r 'wdir()' -T '{node|shortest}\n'
2366 ffff
2367
2368 $ hg log --template '{shortest("f")}\n' -l1
2369 f
2370
2371 $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1
2372 0123456789012345678901234567890123456789
2373
2374 $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1
2375 01234567890123456789012345678901234567890123456789
2376
2377 $ hg log --template '{shortest("not a hex string")}\n' -l1
2378 not a hex string
2379
2380 $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1
2381 not a hex string, but it's 40 bytes long
2382
2383 $ hg log --template '{shortest("ffffffffffffffffffffffffffffffffffffffff")}\n' -l1
2384 ffff
2385
2386 $ hg log --template '{shortest("fffffff")}\n' -l1
2387 ffff
2388
2389 $ hg log --template '{shortest("ff")}\n' -l1
2390 ffff
2391
2392 $ cd ..
2393
2394 Test shortest(node) with the repo having short hash collision:
2395
2396 $ hg init hashcollision
2397 $ cd hashcollision
2398 $ cat <<EOF >> .hg/hgrc
2399 > [experimental]
2400 > evolution.createmarkers=True
2401 > EOF
2402 $ echo 0 > a
2403 $ hg ci -qAm 0
2404 $ for i in 17 129 248 242 480 580 617 1057 2857 4025; do
2405 > hg up -q 0
2406 > echo $i > a
2407 > hg ci -qm $i
2408 > done
2409 $ hg up -q null
2410 $ hg log -r0: -T '{rev}:{node}\n'
2411 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
2412 1:11424df6dc1dd4ea255eae2b58eaca7831973bbc
2413 2:11407b3f1b9c3e76a79c1ec5373924df096f0499
2414 3:11dd92fe0f39dfdaacdaa5f3997edc533875cfc4
2415 4:10776689e627b465361ad5c296a20a487e153ca4
2416 5:a00be79088084cb3aff086ab799f8790e01a976b
2417 6:a0b0acd79b4498d0052993d35a6a748dd51d13e6
2418 7:a0457b3450b8e1b778f1163b31a435802987fe5d
2419 8:c56256a09cd28e5764f32e8e2810d0f01e2e357a
2420 9:c5623987d205cd6d9d8389bfc40fff9dbb670b48
2421 10:c562ddd9c94164376c20b86b0b4991636a3bf84f
2422 $ hg debugobsolete a00be79088084cb3aff086ab799f8790e01a976b
2423 obsoleted 1 changesets
2424 $ hg debugobsolete c5623987d205cd6d9d8389bfc40fff9dbb670b48
2425 obsoleted 1 changesets
2426 $ hg debugobsolete c562ddd9c94164376c20b86b0b4991636a3bf84f
2427 obsoleted 1 changesets
2428
2429 nodes starting with '11' (we don't have the revision number '11' though)
2430
2431 $ hg log -r 1:3 -T '{rev}:{shortest(node, 0)}\n'
2432 1:1142
2433 2:1140
2434 3:11d
2435
2436 '5:a00' is hidden, but still we have two nodes starting with 'a0'
2437
2438 $ hg log -r 6:7 -T '{rev}:{shortest(node, 0)}\n'
2439 6:a0b
2440 7:a04
2441
2442 node '10' conflicts with the revision number '10' even if it is hidden
2443 (we could exclude hidden revision numbers, but currently we don't)
2444
2445 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n'
2446 4:107
2447 $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden
2448 4:107
2449
2450 node 'c562' should be unique if the other 'c562' nodes are hidden
2451 (but we don't try the slow path to filter out hidden nodes for now)
2452
2453 $ hg log -r 8 -T '{rev}:{node|shortest}\n'
2454 8:c5625
2455 $ hg log -r 8:10 -T '{rev}:{node|shortest}\n' --hidden
2456 8:c5625
2457 9:c5623
2458 10:c562d
2459
2460 $ cd ..
2461
2462 Test pad function
2463
2464 $ cd r
2465
2466 $ hg log --template '{pad(rev, 20)} {author|user}\n'
2467 2 test
2468 1 {node|short}
2469 0 test
2470
2471 $ hg log --template '{pad(rev, 20, " ", True)} {author|user}\n'
2472 2 test
2473 1 {node|short}
2474 0 test
2475
2476 $ hg log --template '{pad(rev, 20, "-", False)} {author|user}\n'
2477 2------------------- test
2478 1------------------- {node|short}
2479 0------------------- test
2480
2481 Test template string in pad function
2482
2483 $ hg log -r 0 -T '{pad("\{{rev}}", 10)} {author|user}\n'
2484 {0} test
2485
2486 $ hg log -r 0 -T '{pad(r"\{rev}", 10)} {author|user}\n'
2487 \{rev} test
2488
2489 Test width argument passed to pad function
2490
2491 $ hg log -r 0 -T '{pad(rev, "1{"0"}")} {author|user}\n'
2492 0 test
2493 $ hg log -r 0 -T '{pad(rev, "not an int")}\n'
2494 hg: parse error: pad() expects an integer width
2495 [255]
2496
2497 Test invalid fillchar passed to pad function
2498
2499 $ hg log -r 0 -T '{pad(rev, 10, "")}\n'
2500 hg: parse error: pad() expects a single fill character
2501 [255]
2502 $ hg log -r 0 -T '{pad(rev, 10, "--")}\n'
2503 hg: parse error: pad() expects a single fill character
2504 [255]
2505
2506 Test boolean argument passed to pad function
2507
2508 no crash
2509
2510 $ hg log -r 0 -T '{pad(rev, 10, "-", "f{"oo"}")}\n'
2511 ---------0
2512
2513 string/literal
2514
2515 $ hg log -r 0 -T '{pad(rev, 10, "-", "false")}\n'
2516 ---------0
2517 $ hg log -r 0 -T '{pad(rev, 10, "-", false)}\n'
2518 0---------
2519 $ hg log -r 0 -T '{pad(rev, 10, "-", "")}\n'
2520 0---------
2521
2522 unknown keyword is evaluated to ''
2523
2524 $ hg log -r 0 -T '{pad(rev, 10, "-", unknownkeyword)}\n'
2525 0---------
2526
2527 Test separate function
2528
2529 $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
2530 a-b-c
2531 $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
2532 0:f7769ec2ab97 test default
2533 $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
2534 a \x1b[0;31mb\x1b[0m c d (esc)
2535
2536 Test boolean expression/literal passed to if function
2537
2538 $ hg log -r 0 -T '{if(rev, "rev 0 is True")}\n'
2539 rev 0 is True
2540 $ hg log -r 0 -T '{if(0, "literal 0 is True as well")}\n'
2541 literal 0 is True as well
2542 $ hg log -r 0 -T '{if("", "", "empty string is False")}\n'
2543 empty string is False
2544 $ hg log -r 0 -T '{if(revset(r"0 - 0"), "", "empty list is False")}\n'
2545 empty list is False
2546 $ hg log -r 0 -T '{if(revset(r"0"), "non-empty list is True")}\n'
2547 non-empty list is True
2548 $ hg log -r 0 -T '{if(revset(r"0") % "", "list of empty strings is True")}\n'
2549 list of empty strings is True
2550 $ hg log -r 0 -T '{if(true, "true is True")}\n'
2551 true is True
2552 $ hg log -r 0 -T '{if(false, "", "false is False")}\n'
2553 false is False
2554 $ hg log -r 0 -T '{if("false", "non-empty string is True")}\n'
2555 non-empty string is True
2556
2557 Test ifcontains function
2558
2559 $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'
2560 2 is in the string
2561 1 is not
2562 0 is in the string
2563
2564 $ hg log -T '{rev} {ifcontains(rev, "2 two{" 0"}", "is in the string", "is not")}\n'
2565 2 is in the string
2566 1 is not
2567 0 is in the string
2568
2569 $ hg log --template '{rev} {ifcontains("a", file_adds, "added a", "did not add a")}\n'
2570 2 did not add a
2571 1 did not add a
2572 0 added a
2573
2574 $ hg log --debug -T '{rev}{ifcontains(1, parents, " is parent of 1")}\n'
2575 2 is parent of 1
2576 1
2577 0
2578
2579 $ hg log -l1 -T '{ifcontains("branch", extras, "t", "f")}\n'
2580 t
2581 $ hg log -l1 -T '{ifcontains("branch", extras % "{key}", "t", "f")}\n'
2582 t
2583 $ hg log -l1 -T '{ifcontains("branc", extras % "{key}", "t", "f")}\n'
2584 f
2585 $ hg log -l1 -T '{ifcontains("branc", stringify(extras % "{key}"), "t", "f")}\n'
2586 t
2587
2588 Test revset function
2589
2590 $ hg log --template '{rev} {ifcontains(rev, revset("."), "current rev", "not current rev")}\n'
2591 2 current rev
2592 1 not current rev
2593 0 not current rev
2594
2595 $ hg log --template '{rev} {ifcontains(rev, revset(". + .^"), "match rev", "not match rev")}\n'
2596 2 match rev
2597 1 match rev
2598 0 not match rev
2599
2600 $ hg log -T '{ifcontains(desc, revset(":"), "", "type not match")}\n' -l1
2601 type not match
2602
2603 $ hg log --template '{rev} Parents: {revset("parents(%s)", rev)}\n'
2604 2 Parents: 1
2605 1 Parents: 0
2606 0 Parents:
2607
2608 $ cat >> .hg/hgrc <<EOF
2609 > [revsetalias]
2610 > myparents(\$1) = parents(\$1)
2611 > EOF
2612 $ hg log --template '{rev} Parents: {revset("myparents(%s)", rev)}\n'
2613 2 Parents: 1
2614 1 Parents: 0
2615 0 Parents:
2616
2617 $ hg log --template 'Rev: {rev}\n{revset("::%s", rev) % "Ancestor: {revision}\n"}\n'
2618 Rev: 2
2619 Ancestor: 0
2620 Ancestor: 1
2621 Ancestor: 2
2622
2623 Rev: 1
2624 Ancestor: 0
2625 Ancestor: 1
2626
2627 Rev: 0
2628 Ancestor: 0
2629
2630 $ hg log --template '{revset("TIP"|lower)}\n' -l1
2631 2
2632
2633 $ hg log -T '{revset("%s", "t{"ip"}")}\n' -l1
2634 2
2635
2636 a list template is evaluated for each item of revset/parents
2637
2638 $ hg log -T '{rev} p: {revset("p1(%s)", rev) % "{rev}:{node|short}"}\n'
2639 2 p: 1:bcc7ff960b8e
2640 1 p: 0:f7769ec2ab97
2641 0 p:
2642
2643 $ hg log --debug -T '{rev} p:{parents % " {rev}:{node|short}"}\n'
2644 2 p: 1:bcc7ff960b8e -1:000000000000
2645 1 p: 0:f7769ec2ab97 -1:000000000000
2646 0 p: -1:000000000000 -1:000000000000
2647
2648 therefore, 'revcache' should be recreated for each rev
2649
2650 $ hg log -T '{rev} {file_adds}\np {revset("p1(%s)", rev) % "{file_adds}"}\n'
2651 2 aa b
2652 p
2653 1
2654 p a
2655 0 a
2656 p
2657
2658 $ hg log --debug -T '{rev} {file_adds}\np {parents % "{file_adds}"}\n'
2659 2 aa b
2660 p
2661 1
2662 p a
2663 0 a
2664 p
2665
2666 a revset item must be evaluated as an integer revision, not an offset from tip
2667
2668 $ hg log -l 1 -T '{revset("null") % "{rev}:{node|short}"}\n'
2669 -1:000000000000
2670 $ hg log -l 1 -T '{revset("%s", "null") % "{rev}:{node|short}"}\n'
2671 -1:000000000000
2672
2673 join() should pick '{rev}' from revset items:
2674
2675 $ hg log -R ../a -T '{join(revset("parents(%d)", rev), ", ")}\n' -r6
2676 4, 5
2677
2678 on the other hand, parents are formatted as '{rev}:{node|formatnode}' by
2679 default. join() should agree with the default formatting:
2680
2681 $ hg log -R ../a -T '{join(parents, ", ")}\n' -r6
2682 5:13207e5a10d9, 4:bbe44766e73d
2683
2684 $ hg log -R ../a -T '{join(parents, ",\n")}\n' -r6 --debug
2685 5:13207e5a10d9fd28ec424934298e176197f2c67f,
2686 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
2687
2688 Invalid arguments passed to revset()
2689
2690 $ hg log -T '{revset("%whatever", 0)}\n'
2691 hg: parse error: unexpected revspec format character w
2692 [255]
2693 $ hg log -T '{revset("%lwhatever", files)}\n'
2694 hg: parse error: unexpected revspec format character w
2695 [255]
2696 $ hg log -T '{revset("%s %s", 0)}\n'
2697 hg: parse error: missing argument for revspec
2698 [255]
2699 $ hg log -T '{revset("", 0)}\n'
2700 hg: parse error: too many revspec arguments specified
2701 [255]
2702 $ hg log -T '{revset("%s", 0, 1)}\n'
2703 hg: parse error: too many revspec arguments specified
2704 [255]
2705 $ hg log -T '{revset("%", 0)}\n'
2706 hg: parse error: incomplete revspec format character
2707 [255]
2708 $ hg log -T '{revset("%l", 0)}\n'
2709 hg: parse error: incomplete revspec format character
2710 [255]
2711 $ hg log -T '{revset("%d", 'foo')}\n'
2712 hg: parse error: invalid argument for revspec
2713 [255]
2714 $ hg log -T '{revset("%ld", files)}\n'
2715 hg: parse error: invalid argument for revspec
2716 [255]
2717 $ hg log -T '{revset("%ls", 0)}\n'
2718 hg: parse error: invalid argument for revspec
2719 [255]
2720 $ hg log -T '{revset("%b", 'foo')}\n'
2721 hg: parse error: invalid argument for revspec
2722 [255]
2723 $ hg log -T '{revset("%lb", files)}\n'
2724 hg: parse error: invalid argument for revspec
2725 [255]
2726 $ hg log -T '{revset("%r", 0)}\n'
2727 hg: parse error: invalid argument for revspec
2728 [255]
2729 1755
2730 Test 'originalnode' 1756 Test 'originalnode'
2731 1757
2732 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n' 1758 $ hg log -r 1 -T '{revset("null") % "{node|short} {originalnode|short}"}\n'
2733 000000000000 bcc7ff960b8e 1759 000000000000 bcc7ff960b8e
2734 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n' 1760 $ hg log -r 0 -T '{manifest % "{node} {originalnode}"}\n'
2735 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1 1761 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 f7769ec2ab975ad19684098ad1ffd9b81ecc71a1
2736
2737 Test files function
2738
2739 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
2740 2
2741 a
2742 aa
2743 b
2744 1
2745 a
2746 0
2747 a
2748
2749 $ hg log -T "{rev}\n{join(files('aa'), '\n')}\n"
2750 2
2751 aa
2752 1
2753
2754 0
2755
2756 $ hg rm a
2757 $ hg log -r "wdir()" -T "{rev}\n{join(files('*'), '\n')}\n"
2758 2147483647
2759 aa
2760 b
2761 $ hg revert a
2762
2763 Test relpath function
2764
2765 $ hg log -r0 -T '{files % "{file|relpath}\n"}'
2766 a
2767 $ cd ..
2768 $ hg log -R r -r0 -T '{files % "{file|relpath}\n"}'
2769 r/a
2770 $ cd r
2771 1762
2772 Test active bookmark templating 1763 Test active bookmark templating
2773 1764
2774 $ hg book foo 1765 $ hg book foo
2775 $ hg book bar 1766 $ hg book bar
2846 foo 1837 foo
2847 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}' 1838 $ hg log -r2 -T '{namespaces.bookmarks % "{bookmark}\n"}'
2848 bar 1839 bar
2849 foo 1840 foo
2850 1841
2851 Test stringify on sub expressions
2852
2853 $ cd .. 1842 $ cd ..
2854 $ hg log -R a -r 8 --template '{join(files, if("1", if("1", ", ")))}\n'
2855 fourth, second, third
2856 $ hg log -R a -r 8 --template '{strip(if("1", if("1", "-abc-")), if("1", if("1", "-")))}\n'
2857 abc
2858
2859 Test splitlines
2860
2861 $ hg log -Gv -R a --template "{splitlines(desc) % 'foo {line}\n'}"
2862 @ foo Modify, add, remove, rename
2863 |
2864 o foo future
2865 |
2866 o foo third
2867 |
2868 o foo second
2869
2870 o foo merge
2871 |\
2872 | o foo new head
2873 | |
2874 o | foo new branch
2875 |/
2876 o foo no user, no domain
2877 |
2878 o foo no person
2879 |
2880 o foo other 1
2881 | foo other 2
2882 | foo
2883 | foo other 3
2884 o foo line 1
2885 foo line 2
2886
2887 $ hg log -R a -r0 -T '{desc|splitlines}\n'
2888 line 1 line 2
2889 $ hg log -R a -r0 -T '{join(desc|splitlines, "|")}\n'
2890 line 1|line 2
2891
2892 Test startswith
2893 $ hg log -Gv -R a --template "{startswith(desc)}"
2894 hg: parse error: startswith expects two arguments
2895 [255]
2896
2897 $ hg log -Gv -R a --template "{startswith('line', desc)}"
2898 @
2899 |
2900 o
2901 |
2902 o
2903 |
2904 o
2905
2906 o
2907 |\
2908 | o
2909 | |
2910 o |
2911 |/
2912 o
2913 |
2914 o
2915 |
2916 o
2917 |
2918 o line 1
2919 line 2
2920 1843
2921 Test bad template with better error message 1844 Test bad template with better error message
2922 1845
2923 $ hg log -Gv -R a --template '{desc|user()}' 1846 $ hg log -Gv -R a --template '{desc|user()}'
2924 hg: parse error: expected a symbol, got 'func' 1847 hg: parse error: expected a symbol, got 'func'
2925 [255] 1848 [255]
2926 1849
2927 Test word function (including index out of bounds graceful failure)
2928
2929 $ hg log -Gv -R a --template "{word('1', desc)}"
2930 @ add,
2931 |
2932 o
2933 |
2934 o
2935 |
2936 o
2937
2938 o
2939 |\
2940 | o head
2941 | |
2942 o | branch
2943 |/
2944 o user,
2945 |
2946 o person
2947 |
2948 o 1
2949 |
2950 o 1
2951
2952
2953 Test word third parameter used as splitter
2954
2955 $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
2956 @ M
2957 |
2958 o future
2959 |
2960 o third
2961 |
2962 o sec
2963
2964 o merge
2965 |\
2966 | o new head
2967 | |
2968 o | new branch
2969 |/
2970 o n
2971 |
2972 o n
2973 |
2974 o
2975 |
2976 o line 1
2977 line 2
2978
2979 Test word error messages for not enough and too many arguments
2980
2981 $ hg log -Gv -R a --template "{word('0')}"
2982 hg: parse error: word expects two or three arguments, got 1
2983 [255]
2984
2985 $ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
2986 hg: parse error: word expects two or three arguments, got 7
2987 [255]
2988
2989 Test word for integer literal
2990
2991 $ hg log -R a --template "{word(2, desc)}\n" -r0
2992 line
2993
2994 Test word for invalid numbers
2995
2996 $ hg log -Gv -R a --template "{word('a', desc)}"
2997 hg: parse error: word expects an integer index
2998 [255]
2999
3000 Test word for out of range
3001
3002 $ hg log -R a --template "{word(10000, desc)}"
3003 $ hg log -R a --template "{word(-10000, desc)}"
3004
3005 Test indent and not adding to empty lines
3006
3007 $ hg log -T "-----\n{indent(desc, '>> ', ' > ')}\n" -r 0:1 -R a
3008 -----
3009 > line 1
3010 >> line 2
3011 -----
3012 > other 1
3013 >> other 2
3014
3015 >> other 3
3016
3017 Test with non-strings like dates
3018
3019 $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a
3020 1200000.00
3021 1300000.00
3022
3023 Test broken string escapes: 1850 Test broken string escapes:
3024 1851
3025 $ hg log -T "bogus\\" -R a 1852 $ hg log -T "bogus\\" -R a
3026 hg: parse error: trailing \ in string 1853 hg: parse error: trailing \ in string
3027 [255] 1854 [255]
3028 $ hg log -T "\\xy" -R a 1855 $ hg log -T "\\xy" -R a
3029 hg: parse error: invalid \x escape* (glob) 1856 hg: parse error: invalid \x escape* (glob)
3030 [255] 1857 [255]
3031
3032 json filter should escape HTML tags so that the output can be embedded in hgweb:
3033
3034 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
3035 "\u003cfoo@example.org\u003e"
3036 1858
3037 Templater supports aliases of symbol and func() styles: 1859 Templater supports aliases of symbol and func() styles:
3038 1860
3039 $ hg clone -q a aliases 1861 $ hg clone -q a aliases
3040 $ cd aliases 1862 $ cd aliases
3157 abort: bad definition of template alias "bad": at 2: not a prefix: end 1979 abort: bad definition of template alias "bad": at 2: not a prefix: end
3158 [255] 1980 [255]
3159 $ hg log --config templatealias.bad='x(' -T '{bad}' 1981 $ hg log --config templatealias.bad='x(' -T '{bad}'
3160 abort: bad definition of template alias "bad": at 2: not a prefix: end 1982 abort: bad definition of template alias "bad": at 2: not a prefix: end
3161 [255] 1983 [255]
3162
3163 $ cd ..
3164
3165 Set up repository for non-ascii encoding tests:
3166
3167 $ hg init nonascii
3168 $ cd nonascii
3169 $ $PYTHON <<EOF
3170 > open('latin1', 'wb').write(b'\xe9')
3171 > open('utf-8', 'wb').write(b'\xc3\xa9')
3172 > EOF
3173 $ HGENCODING=utf-8 hg branch -q `cat utf-8`
3174 $ HGENCODING=utf-8 hg ci -qAm "non-ascii branch: `cat utf-8`" utf-8
3175
3176 json filter should try round-trip conversion to utf-8:
3177
3178 $ HGENCODING=ascii hg log -T "{branch|json}\n" -r0
3179 "\u00e9"
3180 $ HGENCODING=ascii hg log -T "{desc|json}\n" -r0
3181 "non-ascii branch: \u00e9"
3182
3183 json filter should take input as utf-8 if it was converted from utf-8:
3184
3185 $ HGENCODING=latin-1 hg log -T "{branch|json}\n" -r0
3186 "\u00e9"
3187 $ HGENCODING=latin-1 hg log -T "{desc|json}\n" -r0
3188 "non-ascii branch: \u00e9"
3189
3190 json filter takes input as utf-8b:
3191
3192 $ HGENCODING=ascii hg log -T "{'`cat utf-8`'|json}\n" -l1
3193 "\u00e9"
3194 $ HGENCODING=ascii hg log -T "{'`cat latin1`'|json}\n" -l1
3195 "\udce9"
3196
3197 utf8 filter:
3198
3199 $ HGENCODING=ascii hg log -T "round-trip: {branch|utf8|hex}\n" -r0
3200 round-trip: c3a9
3201 $ HGENCODING=latin1 hg log -T "decoded: {'`cat latin1`'|utf8|hex}\n" -l1
3202 decoded: c3a9
3203 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
3204 abort: decoding near * (glob)
3205 [255]
3206 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
3207 coerced to string: 0
3208
3209 pad width:
3210
3211 $ HGENCODING=utf-8 hg debugtemplate "{pad('`cat utf-8`', 2, '-')}\n"
3212 \xc3\xa9- (esc)
3213 1984
3214 $ cd .. 1985 $ cd ..
3215 1986
3216 Test that template function in extension is registered as expected 1987 Test that template function in extension is registered as expected
3217 1988