Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

118 rader
6.3 KiB

#include <catch2/catch_test_macros.hpp>
#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<token> 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<scripting::script_error> 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<token> 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<scripting::script_error> 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<const std::string>("/salad 12 13 \"hello\" ident");
auto line2 = line1;
auto line3 = std::make_shared<const std::string>("if(/test)");
auto line4 = std::make_shared<const std::string>(" /nice");
auto line5 = std::make_shared<const std::string>("endif");
using cl = scripting::code_location;
std::vector<token> expected = {
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 1}), .value = symbol_t::divide},
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 2}), .value = identifier{.value = "salad"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 8}), .value = 12},
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 11}), .value = 13},
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 14}), .value = "hello"},
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 22}), .value = identifier{.value = "ident"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line1, .line_number = 1, .column_number = 27}), .value = symbol_t::new_line},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 1}), .value = symbol_t::divide},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 2}), .value = identifier{.value = "salad"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 8}), .value = 12},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 11}), .value = 13},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 14}), .value = "hello"},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 22}), .value = identifier{.value = "ident"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line2, .line_number = 2, .column_number = 27}), .value = symbol_t::new_line},
token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 1}), .value = identifier{.value = "if"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 3}), .value = symbol_t::l_paren},
token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 4}), .value = symbol_t::divide},
token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 5}), .value = identifier{.value = "test"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 9}), .value = symbol_t::r_paren},
token{.location = std::make_shared<cl>(cl{.line_contents = line3, .line_number = 3, .column_number = 10}), .value = symbol_t::new_line},
token{.location = std::make_shared<cl>(cl{.line_contents = line4, .line_number = 4, .column_number = 5}), .value = symbol_t::divide},
token{.location = std::make_shared<cl>(cl{.line_contents = line4, .line_number = 4, .column_number = 6}), .value = identifier{.value = "nice"}},
token{.location = std::make_shared<cl>(cl{.line_contents = line4, .line_number = 4, .column_number = 10}), .value = symbol_t::new_line},
token{.location = std::make_shared<cl>(cl{.line_contents = line5, .line_number = 5, .column_number = 1}), .value = identifier{.value = "endif"}},
};
std::vector<scripting::script_error> 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));
}
}
}