@@ -937,3 +937,191 @@ TEST(real_world_tests, template_string_expression_ambiguity) {
937937 ASSERT_EQ (result->exports [1 ], " b" );
938938 SUCCEED ();
939939}
940+
941+ TEST (real_world_tests, export_star_failure) {
942+ // This should not crash - __exportStar with non-require argument
943+ auto result = lexer::parse_commonjs (" __exportStar((0));" );
944+ ASSERT_TRUE (result.has_value ());
945+ SUCCEED ();
946+ }
947+
948+ TEST (real_world_tests, esm_syntax_error_import) {
949+ auto result = lexer::parse_commonjs (" \n import 'x';\n " );
950+ ASSERT_FALSE (result.has_value ());
951+ auto err = lexer::get_last_error ();
952+ ASSERT_TRUE (err.has_value ());
953+ ASSERT_EQ (err, lexer::lexer_error::UNEXPECTED_ESM_IMPORT);
954+ }
955+
956+ TEST (real_world_tests, esm_syntax_error_export) {
957+ auto result = lexer::parse_commonjs (" \n export { x };\n " );
958+ ASSERT_FALSE (result.has_value ());
959+ auto err = lexer::get_last_error ();
960+ ASSERT_TRUE (err.has_value ());
961+ ASSERT_EQ (err, lexer::lexer_error::UNEXPECTED_ESM_EXPORT);
962+ }
963+
964+ TEST (real_world_tests, esm_syntax_error_export_function) {
965+ auto result = lexer::parse_commonjs (" \n syntax?error;\n\n export function x () {\n\n }\n " );
966+ ASSERT_FALSE (result.has_value ());
967+ auto err = lexer::get_last_error ();
968+ ASSERT_TRUE (err.has_value ());
969+ ASSERT_EQ (err, lexer::lexer_error::UNEXPECTED_ESM_EXPORT);
970+ }
971+
972+ TEST (real_world_tests, esm_syntax_error_import_meta) {
973+ auto result = lexer::parse_commonjs (" \n import.meta.url\n " );
974+ ASSERT_FALSE (result.has_value ());
975+ auto err = lexer::get_last_error ();
976+ ASSERT_TRUE (err.has_value ());
977+ ASSERT_EQ (err, lexer::lexer_error::UNEXPECTED_ESM_IMPORT_META);
978+ }
979+
980+ TEST (real_world_tests, unicode_escape_sequences) {
981+ // Test various unicode escape sequences in exports
982+ auto result = lexer::parse_commonjs (" \
983+ exports['\\ u58b8'] = 1;\
984+ exports['\\ n'] = 1;\
985+ exports['\\ xFF'] = 1;\
986+ exports['\\ 011'] = 1;\
987+ exports['\\ 3z'] = 1;\
988+ " );
989+ ASSERT_TRUE (result.has_value ());
990+ // The lexer preserves escape sequences as-is
991+ ASSERT_EQ (result->exports .size (), 5 );
992+ SUCCEED ();
993+ }
994+
995+ TEST (real_world_tests, empty_source) {
996+ auto result = lexer::parse_commonjs (" " );
997+ ASSERT_TRUE (result.has_value ());
998+ ASSERT_EQ (result->exports .size (), 0 );
999+ ASSERT_EQ (result->re_exports .size (), 0 );
1000+ SUCCEED ();
1001+ }
1002+
1003+ TEST (real_world_tests, whitespace_only) {
1004+ auto result = lexer::parse_commonjs (" \n\t\r\n " );
1005+ ASSERT_TRUE (result.has_value ());
1006+ ASSERT_EQ (result->exports .size (), 0 );
1007+ ASSERT_EQ (result->re_exports .size (), 0 );
1008+ SUCCEED ();
1009+ }
1010+
1011+ TEST (real_world_tests, nested_require) {
1012+ auto result = lexer::parse_commonjs (" \
1013+ const a = require('a');\
1014+ const b = require('b').default;\
1015+ const { c } = require('c');\
1016+ " );
1017+ ASSERT_TRUE (result.has_value ());
1018+ ASSERT_EQ (result->exports .size (), 0 );
1019+ ASSERT_EQ (result->re_exports .size (), 0 );
1020+ SUCCEED ();
1021+ }
1022+
1023+ TEST (real_world_tests, conditional_exports) {
1024+ auto result = lexer::parse_commonjs (" \
1025+ if (condition) {\
1026+ exports.a = 1;\
1027+ } else {\
1028+ exports.b = 2;\
1029+ }\
1030+ " );
1031+ ASSERT_TRUE (result.has_value ());
1032+ // Both exports should be detected
1033+ ASSERT_EQ (result->exports .size (), 2 );
1034+ ASSERT_EQ (result->exports [0 ], " a" );
1035+ ASSERT_EQ (result->exports [1 ], " b" );
1036+ SUCCEED ();
1037+ }
1038+
1039+ TEST (real_world_tests, exports_in_function) {
1040+ auto result = lexer::parse_commonjs (" \
1041+ function setup() {\
1042+ exports.internal = 1;\
1043+ }\
1044+ exports.external = 2;\
1045+ " );
1046+ ASSERT_TRUE (result.has_value ());
1047+ // Both exports should be detected (lexer doesn't track scope)
1048+ ASSERT_EQ (result->exports .size (), 2 );
1049+ SUCCEED ();
1050+ }
1051+
1052+ TEST (real_world_tests, multiple_module_exports_assign) {
1053+ auto result = lexer::parse_commonjs (" \
1054+ module.exports = { a: 1 };\
1055+ module.exports = { b: 2 };\
1056+ " );
1057+ ASSERT_TRUE (result.has_value ());
1058+ // Both should be detected
1059+ ASSERT_GE (result->exports .size (), 1 );
1060+ SUCCEED ();
1061+ }
1062+
1063+ TEST (real_world_tests, string_with_keywords) {
1064+ // Strings containing keywords should not trigger ESM detection
1065+ auto result = lexer::parse_commonjs (" \
1066+ const str1 = 'import x from y';\
1067+ const str2 = \" export default foo\" ;\
1068+ const str3 = `import.meta.url`;\
1069+ exports.a = 1;\
1070+ " );
1071+ ASSERT_TRUE (result.has_value ());
1072+ ASSERT_EQ (result->exports .size (), 1 );
1073+ ASSERT_EQ (result->exports [0 ], " a" );
1074+ SUCCEED ();
1075+ }
1076+
1077+ TEST (real_world_tests, comment_with_keywords) {
1078+ // Comments containing keywords should not trigger ESM detection
1079+ auto result = lexer::parse_commonjs (" \
1080+ // import x from y\n \
1081+ /* export default foo */\
1082+ exports.a = 1;\
1083+ " );
1084+ ASSERT_TRUE (result.has_value ());
1085+ ASSERT_EQ (result->exports .size (), 1 );
1086+ ASSERT_EQ (result->exports [0 ], " a" );
1087+ SUCCEED ();
1088+ }
1089+
1090+ TEST (real_world_tests, complex_object_literal) {
1091+ auto result = lexer::parse_commonjs (" \
1092+ module.exports = {\
1093+ foo: 'bar',\
1094+ baz: function() {},\
1095+ qux: () => {},\
1096+ nested: { a: 1 }\
1097+ };\
1098+ " );
1099+ ASSERT_TRUE (result.has_value ());
1100+ // Only simple key-value pairs are detected
1101+ ASSERT_GE (result->exports .size (), 1 );
1102+ SUCCEED ();
1103+ }
1104+
1105+ TEST (real_world_tests, prototype_exports) {
1106+ auto result = lexer::parse_commonjs (" \
1107+ function MyClass() {}\
1108+ MyClass.prototype.method = function() {};\
1109+ module.exports = MyClass;\
1110+ " );
1111+ ASSERT_TRUE (result.has_value ());
1112+ // No named exports, just the default
1113+ SUCCEED ();
1114+ }
1115+
1116+ TEST (real_world_tests, exports_shorthand_syntax) {
1117+ auto result = lexer::parse_commonjs (" \
1118+ const a = 1, b = 2, c = 3;\
1119+ module.exports = { a, b, c };\
1120+ " );
1121+ ASSERT_TRUE (result.has_value ());
1122+ ASSERT_EQ (result->exports .size (), 3 );
1123+ ASSERT_EQ (result->exports [0 ], " a" );
1124+ ASSERT_EQ (result->exports [1 ], " b" );
1125+ ASSERT_EQ (result->exports [2 ], " c" );
1126+ SUCCEED ();
1127+ }
0 commit comments