You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
6.3 KiB

преди 1 година
  1. #include <catch2/catch_test_macros.hpp>
  2. #include "UserScript/parser.h"
  3. using token = scripting::ast::token;
  4. using symbol_t = scripting::ast::symbol_t;
  5. using identifier = scripting::ast::identifier;
  6. TEST_CASE("Lexer Test 01") {
  7. std::string code = "/salad 12 13 \"hello\" ident\n";
  8. std::vector<token> expected = {
  9. token{.value = symbol_t::divide},
  10. token{.value = identifier{.value = "salad"}},
  11. token{.value = 12},
  12. token{.value = 13},
  13. token{.value = "hello"},
  14. token{.value = identifier{.value = "ident"}},
  15. token{.value = symbol_t::new_line}
  16. };
  17. std::vector<scripting::script_error> errors;
  18. auto lexed = scripting::ast::lex(code, errors);
  19. REQUIRE(errors.empty());
  20. REQUIRE(lexed.size() == expected.size());
  21. for(size_t idx = 0; idx < lexed.size(); ++idx) {
  22. REQUIRE(lexed[idx].value.index() == expected[idx].value.index());
  23. REQUIRE(lexed[idx].value == expected[idx].value);
  24. }
  25. }
  26. TEST_CASE("Lexer Test 01 (Doubled)") {
  27. std::string code = "/salad 12 13 \"hello\" ident\n/salad 12 13 \"hello\" ident\n";
  28. std::vector<token> expected = {
  29. token{.value = symbol_t::divide},
  30. token{.value = identifier{.value = "salad"}},
  31. token{.value = 12},
  32. token{.value = 13},
  33. token{.value = "hello"},
  34. token{.value = identifier{.value = "ident"}},
  35. token{.value = symbol_t::new_line},
  36. token{.value = symbol_t::divide},
  37. token{.value = identifier{.value = "salad"}},
  38. token{.value = 12},
  39. token{.value = 13},
  40. token{.value = "hello"},
  41. token{.value = identifier{.value = "ident"}},
  42. token{.value = symbol_t::new_line}
  43. };
  44. std::vector<scripting::script_error> errors;
  45. auto lexed = scripting::ast::lex(code, errors);
  46. REQUIRE(errors.empty());
  47. REQUIRE(lexed.size() == expected.size());
  48. for(size_t idx = 0; idx < lexed.size(); ++idx) {
  49. REQUIRE(lexed[idx].value.index() == expected[idx].value.index());
  50. REQUIRE(lexed[idx].value == expected[idx].value);
  51. }
  52. }
  53. TEST_CASE("Lexer Test 02") {
  54. std::string code = "/salad 12 13 \"hello\" ident\n"
  55. "/salad 12 13 \"hello\" ident\n"
  56. "if(/test)\n"
  57. " /nice\n"
  58. "endif";
  59. auto line1 = std::make_shared<const std::string>("/salad 12 13 \"hello\" ident");
  60. auto line2 = line1;
  61. auto line3 = std::make_shared<const std::string>("if(/test)");
  62. auto line4 = std::make_shared<const std::string>(" /nice");
  63. auto line5 = std::make_shared<const std::string>("endif");
  64. using cl = scripting::code_location;
  65. std::vector<token> expected = {
  66. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 1}), .value = symbol_t::divide},
  67. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 2}), .value = identifier{.value = "salad"}},
  68. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 8}), .value = 12},
  69. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 11}), .value = 13},
  70. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 14}), .value = "hello"},
  71. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 22}), .value = identifier{.value = "ident"}},
  72. token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 27}), .value = symbol_t::new_line},
  73. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 1}), .value = symbol_t::divide},
  74. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 2}), .value = identifier{.value = "salad"}},
  75. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 8}), .value = 12},
  76. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 11}), .value = 13},
  77. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 14}), .value = "hello"},
  78. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 22}), .value = identifier{.value = "ident"}},
  79. token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 27}), .value = symbol_t::new_line},
  80. token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 1}), .value = identifier{.value = "if"}},
  81. token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 3}), .value = symbol_t::l_paren},
  82. token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 4}), .value = symbol_t::divide},
  83. token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 5}), .value = identifier{.value = "test"}},
  84. token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 9}), .value = symbol_t::r_paren},
  85. token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 10}), .value = symbol_t::new_line},
  86. token{.location = std::make_shared<cl>(cl{.line_contents = line4, .line_number = 4, .column_number = 5}), .value = symbol_t::divide},
  87. token{.location = std::make_shared<cl>(cl{.line_contents = line4, .line_number = 4, .column_number = 6}), .value = identifier{.value = "nice"}},
  88. token{.location = std::make_shared<cl>(cl{.line_contents = line4, .line_number = 4, .column_number = 10}), .value = symbol_t::new_line},
  89. token{.location = std::make_shared<cl>(cl{.line_contents = line5, .line_number = 5, .column_number = 1}), .value = identifier{.value = "endif"}},
  90. };
  91. std::vector<scripting::script_error> errors;
  92. auto lexed = scripting::ast::lex(code, errors);
  93. REQUIRE(errors.empty());
  94. REQUIRE(lexed.size() == expected.size());
  95. for(size_t idx = 0; idx < lexed.size(); ++idx) {
  96. REQUIRE(lexed[idx].value.index() == expected[idx].value.index());
  97. REQUIRE(lexed[idx].value == expected[idx].value);
  98. REQUIRE(lexed[idx].location);
  99. if(expected[idx].location) {
  100. REQUIRE(expected[idx].location->column_number == lexed[idx].location->column_number);
  101. REQUIRE(expected[idx].location->line_number == lexed[idx].location->line_number);
  102. REQUIRE((bool)lexed[idx].location->line_contents);
  103. REQUIRE(*(expected[idx].location->line_contents) == *(lexed[idx].location->line_contents));
  104. }
  105. }
  106. }