@@ -10,6 +10,10 @@ let assert_template_decoded ~encoded ~expected =
1010 OUnit. assert_equal ~printer: Ext_obj. dump (Some expected)
1111 (String_literal. decode_js_template_escapes encoded)
1212
13+ let assert_invalid_template encoded =
14+ OUnit. assert_equal ~printer: Ext_obj. dump None
15+ (String_literal. decode_js_template_escapes encoded)
16+
1317let assert_encoded ~semantic ~expected =
1418 let encoded = String_literal. encode_js_string semantic in
1519 OUnit. assert_equal ~printer: (Printf. sprintf " %S" ) expected encoded;
@@ -391,6 +395,9 @@ let suites =
391395 OUnit.assert_equal ~printer:Ext_obj.dump None
392396 (String_literal.decode_js_template_escapes encoded))
393397 [{|a\1b|}; {|a\01b|}; {|a\8b|}] );
398+ ( " template segments reject interpolation openers " >:: fun _ ->
399+ assert_invalid_template " ${value} ";
400+ assert_template_decoded ~encoded:" \\${value} " ~expected:" ${value} " );
394401 ( " ordinary literals become semantic strings " >:: fun _ ->
395402 assert_parsed_string ~source:{|\x61\n \uD83D\uDE00|}
396403 ~expected_semantic:" a \n 😀" );
@@ -695,15 +702,42 @@ let suites =
695702 OUnit.assert_equal ~printer:(Printf.sprintf " %S") {e|`\${x}`|e}
696703 (Js_dump.string_of_expression boundary);
697704 let already_escaped_boundary =
705+ Js_exp_make.interpolated_template
706+ [{source = " \\$"; semantic = " $"}; {source = ""; semantic = ""}]
707+ [Js_exp_make.template_literal ~semantic:" {x} " " {x} "]
708+ in
709+ OUnit.assert_equal ~printer:(Printf.sprintf " %S") {e|`\${x}`|e}
710+ (Js_dump.string_of_expression already_escaped_boundary);
711+ let null_digit_boundary =
698712 Js_exp_make.interpolated_template
699713 [
700- {source = {e|\$|e} ; semantic = " $ "};
714+ {source = " \\ 0 " ; semantic = "\ 000 "};
701715 {source = ""; semantic = ""};
702716 ]
703- [Js_exp_make.template_literal ~semantic:" {x} " " {x} "]
717+ [Js_exp_make.template_literal ~semantic:" 1 " " 1 "]
704718 in
705- OUnit.assert_equal ~printer:(Printf.sprintf " %S") {e|`\${x}`|e}
706- (Js_dump.string_of_expression already_escaped_boundary) );
719+ OUnit.assert_equal ~printer:(Printf.sprintf " %S") {e|`\x00 1`|e}
720+ (Js_dump.string_of_expression null_digit_boundary);
721+ let escaped_slash_null_boundary =
722+ Js_exp_make.interpolated_template
723+ [
724+ {source = " \\\\0 "; semantic = " \\0 "};
725+ {source = ""; semantic = ""};
726+ ]
727+ [Js_exp_make.template_literal ~semantic:" 1 " " 1 "]
728+ in
729+ OUnit.assert_equal ~printer:(Printf.sprintf " %S") {e|`\\ 01`|e}
730+ (Js_dump.string_of_expression escaped_slash_null_boundary);
731+ let line_ending_boundary =
732+ Js_exp_make.interpolated_template
733+ [
734+ {source = " a \r "; semantic = " a \n "};
735+ {source = " \nb "; semantic = " \nb "};
736+ ]
737+ [Js_exp_make.template_literal ~semantic:"" ""]
738+ in
739+ OUnit.assert_equal ~printer:(Printf.sprintf " %S") {e|`a\n\n b`|e}
740+ (Js_dump.string_of_expression line_ending_boundary) );
707741 ( " JavaScript references are not encoded as strings " >:: fun _ ->
708742 let value = Js_exp_make.var (Ext_ident.create " value ") in
709743 (match (Js_exp_make.is_array value).expression_desc with
0 commit comments