@@ -810,20 +810,29 @@ def test_tricky_expression(self):
810810 ),
811811 )
812812
813- def test_dict_expression_issue_400_regression (self ):
813+ @pytest .mark .parametrize (
814+ "expr" ,
815+ [
816+ ("${foo}${bar}" ,),
817+ ("file_${foo}_bat_${bar}.py" ,),
818+ ("${foo}_bat_${bar}" ,),
819+ ("${foo}${bar}.py" ,),
820+ ],
821+ )
822+ def test_dict_expression_issue_400_regression (self , expr ):
814823 """test for issue #401.
815824
816825 This was the regression case for #400
817826
818827 """
819- template = '<%include file="${foo}${bar }"/>'
828+ template = f '<%include file="{ expr } "/>'
820829
821830 nodes = Lexer (template ).parse ()
822831 self ._compare (
823832 nodes ,
824833 TemplateNode (
825834 {},
826- [IncludeTag ("include" , {"file" : "${foo}${bar }" }, (1 , 1 ), [])],
835+ [IncludeTag ("include" , {"file" : f" { expr } " }, (1 , 1 ), [])],
827836 ),
828837 )
829838
@@ -838,7 +847,7 @@ def test_ampersand_issue_412(self):
838847 TemplateNode ({}, [Text ("\n property = <&node>;\n \n " , (1 , 1 ))]),
839848 )
840849
841- def _dont_test_dict_expression_issue_400 (self ):
850+ def test_dict_expression_issue_400 (self ):
842851 """test for issue #400"""
843852 template = """
844853 <%def name="dtest(d)">
@@ -897,7 +906,7 @@ def _dont_test_dict_expression_issue_400(self):
897906 ),
898907 )
899908
900- def _dont_test_dict_expression_2_issue_400 (self ):
909+ def test_dict_expression_2_issue_400 (self ):
901910 """test for issue #400"""
902911 template = """
903912 <%def name="thing(thing)">
@@ -1006,6 +1015,213 @@ def _dont_test_dict_expression_2_issue_400(self):
10061015 ),
10071016 )
10081017
1018+ def test_dict_expression (self ):
1019+ template = """
1020+ <%def name="dtest(d)">
1021+ % for k,v in d.items():
1022+ ${k} = ${v}
1023+ % endfor
1024+ </%def>
1025+ <%self:dtest d="${
1026+ {
1027+ 'id':'4',
1028+ 'foo':'barr'
1029+ }
1030+ }" />
1031+ """
1032+ nodes = Lexer (template ).parse ()
1033+ self ._compare (
1034+ nodes ,
1035+ TemplateNode (
1036+ {},
1037+ [
1038+ Text ("\n " , (1 , 1 )),
1039+ DefTag (
1040+ "def" ,
1041+ {"name" : "dtest(d)" },
1042+ (2 , 9 ),
1043+ [
1044+ Text ("\n " , (2 , 31 )),
1045+ ControlLine (
1046+ "for" , "for k,v in d.items():" , False , (3 , 1 )
1047+ ),
1048+ Text (" " , (4 , 1 )),
1049+ Expression ("k" , [], (4 , 13 )),
1050+ Text (" = " , (4 , 17 )),
1051+ Expression ("v" , [], (4 , 20 )),
1052+ Text ("\n " , (4 , 24 )),
1053+ ControlLine ("for" , "endfor" , True , (5 , 1 )),
1054+ Text (" " , (6 , 1 )),
1055+ ],
1056+ ),
1057+ Text ("\n " , (6 , 16 )),
1058+ CallNamespaceTag (
1059+ "self:dtest" ,
1060+ {
1061+ "d" : "${\n \
1062+ {\n \
1063+ 'id':'4',\n \
1064+ 'foo':'barr'\n \
1065+ }\n \
1066+ }"
1067+ },
1068+ (7 , 9 ),
1069+ [],
1070+ ),
1071+ Text ("\n " , (12 , 30 )),
1072+ ],
1073+ ),
1074+ )
1075+
1076+ def test_dict_expression_2 (self ):
1077+ template = """
1078+ <%def name="thing(thing)">
1079+ ${type(thing)}
1080+ </%def>
1081+ <%self:thing thing="foo" />
1082+ <%self:thing thing="${5}" />
1083+ <%self:thing thing="${[1,2,3]}" />
1084+ <%self:thing thing="${{'id':'4'}}" />
1085+ <%
1086+ foo="this is foo"
1087+ g=False
1088+ %>
1089+ <%def name="bar(x, y)">
1090+ ${x} ${y}
1091+ </%def>
1092+ <%self:bar x="${{'id':4}}" y="x${g and '1' or '2'}y"/>
1093+ <%def name="dtest(d)">
1094+ % for k,v in d.items():
1095+ ${k} = ${v}
1096+ % endfor
1097+ % if 'embeded' in d and 'name' in d['embeded']:
1098+ ${d['embeded']['name']}
1099+ % endif
1100+ </%def>
1101+ <%self:dtest d="${ {
1102+ 'x-on:click':'foo',
1103+ 'foo':'bar',
1104+ 'embeded':{'name':'J Doe'}
1105+ } }" />
1106+ """
1107+ nodes = Lexer (template ).parse ()
1108+ self ._compare (
1109+ nodes ,
1110+ TemplateNode (
1111+ {},
1112+ [
1113+ Text ("\n " , (1 , 1 )),
1114+ DefTag (
1115+ "def" ,
1116+ {"name" : "thing(thing)" },
1117+ (2 , 9 ),
1118+ [
1119+ Text ("\n " , (2 , 35 )),
1120+ Expression ("type(thing)" , [], (3 , 13 )),
1121+ Text ("\n " , (3 , 27 )),
1122+ ],
1123+ ),
1124+ Text ("\n " , (4 , 16 )),
1125+ CallNamespaceTag (
1126+ "self:thing" , {"thing" : "foo" }, (5 , 9 ), []
1127+ ),
1128+ Text ("\n " , (5 , 36 )),
1129+ CallNamespaceTag (
1130+ "self:thing" , {"thing" : "${5}" }, (6 , 9 ), []
1131+ ),
1132+ Text ("\n " , (6 , 37 )),
1133+ CallNamespaceTag (
1134+ "self:thing" , {"thing" : "${[1,2,3]}" }, (7 , 9 ), []
1135+ ),
1136+ Text ("\n " , (7 , 43 )),
1137+ CallNamespaceTag (
1138+ "self:thing" , {"thing" : "${{'id':'4'}}" }, (8 , 9 ), []
1139+ ),
1140+ Text ("\n " , (8 , 46 )),
1141+ Code (
1142+ '\n foo="this is foo"\n g=False\n \n ' ,
1143+ False ,
1144+ (9 , 9 ),
1145+ ),
1146+ Text ("\n " , (12 , 11 )),
1147+ DefTag (
1148+ "def" ,
1149+ {"name" : "bar(x, y)" },
1150+ (13 , 9 ),
1151+ [
1152+ Text ("\n " , (13 , 32 )),
1153+ Expression ("x" , [], (14 , 13 )),
1154+ Text (" " , (14 , 17 )),
1155+ Expression ("y" , [], (14 , 18 )),
1156+ Text ("\n " , (14 , 22 )),
1157+ ],
1158+ ),
1159+ Text ("\n " , (15 , 16 )),
1160+ CallNamespaceTag (
1161+ "self:bar" ,
1162+ {"x" : "${{'id':4}}" , "y" : "x${g and '1' or '2'}y" },
1163+ (16 , 9 ),
1164+ [],
1165+ ),
1166+ Text ("\n " , (16 , 63 )),
1167+ DefTag (
1168+ "def" ,
1169+ {"name" : "dtest(d)" },
1170+ (17 , 9 ),
1171+ [
1172+ Text ("\n " , (17 , 31 )),
1173+ ControlLine (
1174+ "for" , "for k,v in d.items():" , False , (18 , 1 )
1175+ ),
1176+ Text (" " , (19 , 1 )),
1177+ Expression ("k" , [], (19 , 9 )),
1178+ Text (" = " , (19 , 13 )),
1179+ Expression ("v" , [], (19 , 16 )),
1180+ Text ("\n " , (19 , 20 )),
1181+ ControlLine ("for" , "endfor" , True , (20 , 1 )),
1182+ ControlLine (
1183+ "if" ,
1184+ "if 'embeded' in d and \
1185+ 'name' in d['embeded']:" ,
1186+ False ,
1187+ (21 , 1 ),
1188+ ),
1189+ Text (" " , (22 , 1 )),
1190+ Expression ("d['embeded']['name']" , [], (22 , 9 )),
1191+ Text ("\n " , (22 , 32 )),
1192+ ControlLine ("if" , "endif" , True , (23 , 1 )),
1193+ Text (" " , (24 , 1 )),
1194+ ],
1195+ ),
1196+ Text ("\n " , (24 , 16 )),
1197+ CallNamespaceTag (
1198+ "self:dtest" ,
1199+ {
1200+ "d" : "${ {\n \
1201+ 'x-on:click':'foo',\n \
1202+ 'foo':'bar',\n \
1203+ 'embeded':{'name':'J Doe'}\n \
1204+ } }"
1205+ },
1206+ (25 , 9 ),
1207+ [],
1208+ ),
1209+ Text ("\n " , (29 , 16 )),
1210+ ],
1211+ ),
1212+ )
1213+
1214+ def test_brace_expression (self ):
1215+ template = '<%include file="${foo}${bar}"/>'
1216+ nodes = Lexer (template ).parse ()
1217+ self ._compare (
1218+ nodes ,
1219+ TemplateNode (
1220+ {},
1221+ [IncludeTag ("include" , {"file" : "${foo}${bar}" }, (1 , 1 ), [])],
1222+ ),
1223+ )
1224+
10091225 def test_tricky_code (self ):
10101226 template = """<% print('hi %>') %>"""
10111227 nodes = Lexer (template ).parse ()
0 commit comments