#include #include "UserScript/parser.h" using token = scripting::ast::token; using symbol_t = scripting::ast::symbol_t; using identifier = scripting::ast::identifier; TEST_CASE("Lexer Test 01") { std::string code = "/salad 12 13 \"hello\" ident\n"; std::vector expected = { token{.value = symbol_t::divide}, token{.value = identifier{.value = "salad"}}, token{.value = 12}, token{.value = 13}, token{.value = "hello"}, token{.value = identifier{.value = "ident"}}, token{.value = symbol_t::new_line} }; std::vector errors; auto lexed = scripting::ast::lex(code, errors); REQUIRE(errors.empty()); REQUIRE(lexed.size() == expected.size()); for(size_t idx = 0; idx < lexed.size(); ++idx) { REQUIRE(lexed[idx].value.index() == expected[idx].value.index()); REQUIRE(lexed[idx].value == expected[idx].value); } } TEST_CASE("Lexer Test 01 (Doubled)") { std::string code = "/salad 12 13 \"hello\" ident\n/salad 12 13 \"hello\" ident\n"; std::vector expected = { token{.value = symbol_t::divide}, token{.value = identifier{.value = "salad"}}, token{.value = 12}, token{.value = 13}, token{.value = "hello"}, token{.value = identifier{.value = "ident"}}, token{.value = symbol_t::new_line}, token{.value = symbol_t::divide}, token{.value = identifier{.value = "salad"}}, token{.value = 12}, token{.value = 13}, token{.value = "hello"}, token{.value = identifier{.value = "ident"}}, token{.value = symbol_t::new_line} }; std::vector errors; auto lexed = scripting::ast::lex(code, errors); REQUIRE(errors.empty()); REQUIRE(lexed.size() == expected.size()); for(size_t idx = 0; idx < lexed.size(); ++idx) { REQUIRE(lexed[idx].value.index() == expected[idx].value.index()); REQUIRE(lexed[idx].value == expected[idx].value); } } TEST_CASE("Lexer Test 02") { std::string code = "/salad 12 13 \"hello\" ident\n" "/salad 12 13 \"hello\" ident\n" "if(/test)\n" " /nice\n" "endif"; auto line1 = std::make_shared("/salad 12 13 \"hello\" ident"); auto line2 = line1; auto line3 = std::make_shared("if(/test)"); auto line4 = std::make_shared(" /nice"); auto line5 = std::make_shared("endif"); using cl = scripting::code_location; std::vector expected = { token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 1}), .value = symbol_t::divide}, token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 2}), .value = identifier{.value = "salad"}}, token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 8}), .value = 12}, token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 11}), .value = 13}, token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 14}), .value = "hello"}, token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 22}), .value = identifier{.value = "ident"}}, token{.location = std::make_shared(cl{.line_contents = line1, .line_number = 1, .column_number = 27}), .value = symbol_t::new_line}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 1}), .value = symbol_t::divide}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 2}), .value = identifier{.value = "salad"}}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 8}), .value = 12}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 11}), .value = 13}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 14}), .value = "hello"}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 22}), .value = identifier{.value = "ident"}}, token{.location = std::make_shared(cl{.line_contents = line2, .line_number = 2, .column_number = 27}), .value = symbol_t::new_line}, token{.location = std::make_shared(cl{.line_contents = line3, .line_number = 3, .column_number = 1}), .value = identifier{.value = "if"}}, token{.location = std::make_shared(cl{.line_contents = line3, .line_number = 3, .column_number = 3}), .value = symbol_t::l_paren}, token{.location = std::make_shared(cl{.line_contents = line3, .line_number = 3, .column_number = 4}), .value = symbol_t::divide}, token{.location = std::make_shared(cl{.line_contents = line3, .line_number = 3, .column_number = 5}), .value = identifier{.value = "test"}}, token{.location = std::make_shared(cl{.line_contents = line3, .line_number = 3, .column_number = 9}), .value = symbol_t::r_paren}, token{.location = std::make_shared(cl{.line_contents = line3, .line_number = 3, .column_number = 10}), .value = symbol_t::new_line}, token{.location = std::make_shared(cl{.line_contents = line4, .line_number = 4, .column_number = 5}), .value = symbol_t::divide}, token{.location = std::make_shared(cl{.line_contents = line4, .line_number = 4, .column_number = 6}), .value = identifier{.value = "nice"}}, token{.location = std::make_shared(cl{.line_contents = line4, .line_number = 4, .column_number = 10}), .value = symbol_t::new_line}, token{.location = std::make_shared(cl{.line_contents = line5, .line_number = 5, .column_number = 1}), .value = identifier{.value = "endif"}}, }; std::vector errors; auto lexed = scripting::ast::lex(code, errors); REQUIRE(errors.empty()); REQUIRE(lexed.size() == expected.size()); for(size_t idx = 0; idx < lexed.size(); ++idx) { REQUIRE(lexed[idx].value.index() == expected[idx].value.index()); REQUIRE(lexed[idx].value == expected[idx].value); REQUIRE(lexed[idx].location); if(expected[idx].location) { REQUIRE(expected[idx].location->column_number == lexed[idx].location->column_number); REQUIRE(expected[idx].location->line_number == lexed[idx].location->line_number); REQUIRE((bool)lexed[idx].location->line_contents); REQUIRE(*(expected[idx].location->line_contents) == *(lexed[idx].location->line_contents)); } } }