Fix indentation in specs
This commit is contained in:
parent
01571da30d
commit
b155994491
34 changed files with 1877 additions and 1878 deletions
|
|
@ -30,46 +30,46 @@ using std::ifstream;
|
|||
using std::istreambuf_iterator;
|
||||
|
||||
static string trim_output(const string &input) {
|
||||
string result(input);
|
||||
result = regex_replace(result, regex("[\n\t ]+", extended), string(" "));
|
||||
result = regex_replace(result, regex("^ ", extended), string(""));
|
||||
result = regex_replace(result, regex(" $", extended), string(""));
|
||||
result = regex_replace(result, regex("\\) \\)", extended), string("))"));
|
||||
return result;
|
||||
string result(input);
|
||||
result = regex_replace(result, regex("[\n\t ]+", extended), string(" "));
|
||||
result = regex_replace(result, regex("^ ", extended), string(""));
|
||||
result = regex_replace(result, regex(" $", extended), string(""));
|
||||
result = regex_replace(result, regex("\\) \\)", extended), string("))"));
|
||||
return result;
|
||||
}
|
||||
|
||||
static vector<TestEntry> get_test_entries_from_string(string content) {
|
||||
regex header_pattern("===+\n" "([^=]+)\n" "===+", extended);
|
||||
regex separator_pattern("---+", extended);
|
||||
vector<string> descriptions;
|
||||
vector<string> bodies;
|
||||
regex header_pattern("===+\n" "([^=]+)\n" "===+", extended);
|
||||
regex separator_pattern("---+", extended);
|
||||
vector<string> descriptions;
|
||||
vector<string> bodies;
|
||||
|
||||
for (;;) {
|
||||
smatch matches;
|
||||
if (!regex_search(content, matches, header_pattern) || matches.empty())
|
||||
break;
|
||||
for (;;) {
|
||||
smatch matches;
|
||||
if (!regex_search(content, matches, header_pattern) || matches.empty())
|
||||
break;
|
||||
|
||||
string description = matches[1].str();
|
||||
descriptions.push_back(description);
|
||||
string description = matches[1].str();
|
||||
descriptions.push_back(description);
|
||||
|
||||
if (!bodies.empty())
|
||||
bodies.back().erase(matches.position());
|
||||
content.erase(0, matches.position() + matches[0].length());
|
||||
bodies.push_back(content);
|
||||
}
|
||||
if (!bodies.empty())
|
||||
bodies.back().erase(matches.position());
|
||||
content.erase(0, matches.position() + matches[0].length());
|
||||
bodies.push_back(content);
|
||||
}
|
||||
|
||||
vector<TestEntry> result;
|
||||
for (size_t i = 0; i < descriptions.size(); i++) {
|
||||
string body = bodies[i];
|
||||
smatch matches;
|
||||
if (regex_search(body, matches, separator_pattern)) {
|
||||
result.push_back({
|
||||
descriptions[i],
|
||||
body.substr(0, matches.position()),
|
||||
trim_output(body.substr(matches.position() + matches[0].length()))
|
||||
});
|
||||
}
|
||||
for (size_t i = 0; i < descriptions.size(); i++) {
|
||||
string body = bodies[i];
|
||||
smatch matches;
|
||||
if (regex_search(body, matches, separator_pattern)) {
|
||||
result.push_back({
|
||||
descriptions[i],
|
||||
body.substr(0, matches.position()),
|
||||
trim_output(body.substr(matches.position() + matches[0].length()))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -79,9 +79,9 @@ static vector<string> list_directory(string dir_name) {
|
|||
|
||||
DIR *dir = opendir(dir_name.c_str());
|
||||
if (!dir) {
|
||||
printf("\nTest error - no such directory '%s'", dir_name.c_str());
|
||||
return result;
|
||||
}
|
||||
printf("\nTest error - no such directory '%s'", dir_name.c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
struct dirent *dir_entry;
|
||||
while ((dir_entry = readdir(dir))) {
|
||||
|
|
@ -90,27 +90,27 @@ static vector<string> list_directory(string dir_name) {
|
|||
result.push_back(dir_name + "/" + name);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
closedir(dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
static string src_dir() {
|
||||
const char *dir = getenv("TREESITTER_DIR");
|
||||
if (!dir) dir = getenv("PWD");
|
||||
return dir;
|
||||
const char *dir = getenv("TREESITTER_DIR");
|
||||
if (!dir) dir = getenv("PWD");
|
||||
return dir;
|
||||
}
|
||||
|
||||
vector<TestEntry> test_entries_for_language(string language) {
|
||||
vector<TestEntry> result;
|
||||
string language_dir = src_dir() + "/spec/runtime/languages/" + language;
|
||||
vector<string> filenames = list_directory(language_dir);
|
||||
vector<TestEntry> result;
|
||||
string language_dir = src_dir() + "/spec/runtime/languages/" + language;
|
||||
vector<string> filenames = list_directory(language_dir);
|
||||
|
||||
for (string &filename : filenames) {
|
||||
ifstream file(filename);
|
||||
std::string content((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
|
||||
for (TestEntry &entry : get_test_entries_from_string(content))
|
||||
result.push_back(entry);
|
||||
}
|
||||
for (string &filename : filenames) {
|
||||
ifstream file(filename);
|
||||
std::string content((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
|
||||
for (TestEntry &entry : get_test_entries_from_string(content))
|
||||
result.push_back(entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include <vector>
|
||||
|
||||
struct TestEntry {
|
||||
std::string description;
|
||||
std::string description;
|
||||
std::string input;
|
||||
std::string tree_string;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,21 +4,21 @@
|
|||
using std::string;
|
||||
|
||||
static const char * spy_read(void *data, size_t *bytes_read) {
|
||||
SpyReader *reader = static_cast<SpyReader *>(data);
|
||||
size_t size = std::min(reader->chunk_size,
|
||||
reader->content.length() - reader->position);
|
||||
const char *result = reader->content.data() + reader->position;
|
||||
reader->strings_read.back() += string(result, size);
|
||||
reader->position += size;
|
||||
*bytes_read = size;
|
||||
return result;
|
||||
SpyReader *reader = static_cast<SpyReader *>(data);
|
||||
size_t size = std::min(reader->chunk_size,
|
||||
reader->content.length() - reader->position);
|
||||
const char *result = reader->content.data() + reader->position;
|
||||
reader->strings_read.back() += string(result, size);
|
||||
reader->position += size;
|
||||
*bytes_read = size;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int spy_seek(void *data, size_t position) {
|
||||
SpyReader *reader = static_cast<SpyReader *>(data);
|
||||
reader->strings_read.push_back("");
|
||||
reader->position = position;
|
||||
return 0;
|
||||
SpyReader *reader = static_cast<SpyReader *>(data);
|
||||
reader->strings_read.push_back("");
|
||||
reader->position = position;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SpyReader::SpyReader(string content, size_t chunk_size) :
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@
|
|||
#include "tree_sitter/runtime.h"
|
||||
|
||||
class SpyReader {
|
||||
public:
|
||||
SpyReader(std::string content, size_t chunk_size);
|
||||
public:
|
||||
SpyReader(std::string content, size_t chunk_size);
|
||||
|
||||
std::string content;
|
||||
size_t position;
|
||||
size_t chunk_size;
|
||||
TSInput input;
|
||||
std::vector<std::string> strings_read;
|
||||
std::string content;
|
||||
size_t position;
|
||||
size_t chunk_size;
|
||||
TSInput input;
|
||||
std::vector<std::string> strings_read;
|
||||
};
|
||||
|
||||
#endif // HELPERS_SPY_READER_H_
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#include "runtime/helpers/tree_helpers.h"
|
||||
|
||||
TSTree ** tree_array(std::vector<TSTree *> trees) {
|
||||
TSTree ** result = (TSTree **)calloc(trees.size(), sizeof(TSTree *));
|
||||
for (size_t i = 0; i < trees.size(); i++)
|
||||
result[i] = trees[i];
|
||||
return result;
|
||||
TSTree ** result = (TSTree **)calloc(trees.size(), sizeof(TSTree *));
|
||||
for (size_t i = 0; i < trees.size(); i++)
|
||||
result[i] = trees[i];
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,37 +9,37 @@ extern "C" const TSLanguage *ts_language_golang();
|
|||
START_TEST
|
||||
|
||||
describe("Languages", [&]() {
|
||||
TSDocument *doc;
|
||||
TSDocument *doc;
|
||||
|
||||
before_each([&]() {
|
||||
doc = ts_document_make();
|
||||
});
|
||||
before_each([&]() {
|
||||
doc = ts_document_make();
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_document_free(doc);
|
||||
});
|
||||
after_each([&]() {
|
||||
ts_document_free(doc);
|
||||
});
|
||||
|
||||
auto run_tests_for_language = [&](string language_name, const TSLanguage *language) {
|
||||
describe(language_name.c_str(), [&]() {
|
||||
before_each([&]() {
|
||||
ts_document_set_language(doc, language);
|
||||
});
|
||||
auto run_tests_for_language = [&](string language_name, const TSLanguage *language) {
|
||||
describe(language_name.c_str(), [&]() {
|
||||
before_each([&]() {
|
||||
ts_document_set_language(doc, language);
|
||||
});
|
||||
|
||||
for (auto &entry : test_entries_for_language(language_name)) {
|
||||
it(entry.description.c_str(), [&]() {
|
||||
ts_document_set_input_string(doc, entry.input.c_str());
|
||||
auto doc_string = ts_document_string(doc);
|
||||
AssertThat(doc_string, Equals(entry.tree_string.c_str()));
|
||||
free((void *)doc_string);
|
||||
});
|
||||
}
|
||||
for (auto &entry : test_entries_for_language(language_name)) {
|
||||
it(entry.description.c_str(), [&]() {
|
||||
ts_document_set_input_string(doc, entry.input.c_str());
|
||||
auto doc_string = ts_document_string(doc);
|
||||
AssertThat(doc_string, Equals(entry.tree_string.c_str()));
|
||||
free((void *)doc_string);
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
run_tests_for_language("json", ts_language_json());
|
||||
run_tests_for_language("arithmetic", ts_language_arithmetic());
|
||||
run_tests_for_language("javascript", ts_language_javascript());
|
||||
run_tests_for_language("golang", ts_language_golang());
|
||||
run_tests_for_language("json", ts_language_json());
|
||||
run_tests_for_language("arithmetic", ts_language_arithmetic());
|
||||
run_tests_for_language("javascript", ts_language_javascript());
|
||||
run_tests_for_language("golang", ts_language_golang());
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
|
|||
|
|
@ -5,104 +5,104 @@ extern "C" TSLanguage * ts_language_json();
|
|||
START_TEST
|
||||
|
||||
describe("Node", []() {
|
||||
TSDocument *document;
|
||||
TSNode *root;
|
||||
TSDocument *document;
|
||||
TSNode *root;
|
||||
|
||||
before_each([&]() {
|
||||
document = ts_document_make();
|
||||
ts_document_set_language(document, ts_language_json());
|
||||
before_each([&]() {
|
||||
document = ts_document_make();
|
||||
ts_document_set_language(document, ts_language_json());
|
||||
|
||||
ts_document_set_input_string(document, " [12, 5, 345]");
|
||||
root = ts_document_root_node(document);
|
||||
AssertThat(ts_node_string(root), Equals("(array (number) (number) (number))"));
|
||||
ts_document_set_input_string(document, " [12, 5, 345]");
|
||||
root = ts_document_root_node(document);
|
||||
AssertThat(ts_node_string(root), Equals("(array (number) (number) (number))"));
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_document_free(document);
|
||||
ts_node_release(root);
|
||||
});
|
||||
|
||||
describe("child_count", [&]() {
|
||||
it("returns the number of visible child nodes", [&]() {
|
||||
AssertThat(ts_node_child_count(root), Equals<size_t>(3));
|
||||
});
|
||||
});
|
||||
|
||||
describe("child(i)", [&]() {
|
||||
it("returns the child node at the given index", [&]() {
|
||||
TSNode *number1 = ts_node_child(root, 0);
|
||||
TSNode *number2 = ts_node_child(root, 1);
|
||||
TSNode *number3 = ts_node_child(root, 2);
|
||||
|
||||
AssertThat(ts_node_name(root), Equals("array"));
|
||||
AssertThat(ts_node_name(number1), Equals("number"));
|
||||
AssertThat(ts_node_name(number2), Equals("number"));
|
||||
AssertThat(ts_node_name(number3), Equals("number"));
|
||||
|
||||
AssertThat(ts_node_pos(root), Equals<size_t>(2));
|
||||
AssertThat(ts_node_size(root), Equals<size_t>(12));
|
||||
|
||||
AssertThat(ts_node_pos(number1), Equals<size_t>(3));
|
||||
AssertThat(ts_node_size(number1), Equals<size_t>(2));
|
||||
|
||||
AssertThat(ts_node_pos(number2), Equals<size_t>(7));
|
||||
AssertThat(ts_node_size(number2), Equals<size_t>(1));
|
||||
|
||||
AssertThat(ts_node_pos(number3), Equals<size_t>(10));
|
||||
AssertThat(ts_node_size(number3), Equals<size_t>(3));
|
||||
|
||||
ts_node_release(number1);
|
||||
ts_node_release(number2);
|
||||
ts_node_release(number3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parent", [&]() {
|
||||
it("returns the node's parent node", [&]() {
|
||||
TSNode *number = ts_node_child(root, 1);
|
||||
AssertThat(ts_node_parent(number), Equals(root));
|
||||
ts_node_release(number);
|
||||
});
|
||||
});
|
||||
|
||||
describe("next_sibling and prev_sibling", [&]() {
|
||||
it("returns the node's next and previous siblings", [&]() {
|
||||
TSNode *number1 = ts_node_child(root, 0);
|
||||
TSNode *number2 = ts_node_child(root, 1);
|
||||
TSNode *number3 = ts_node_child(root, 2);
|
||||
|
||||
AssertThat(ts_node_eq(ts_node_next_sibling(number2), number3), IsTrue());
|
||||
AssertThat(ts_node_eq(ts_node_prev_sibling(number2), number1), IsTrue());
|
||||
|
||||
ts_node_release(number1);
|
||||
ts_node_release(number2);
|
||||
ts_node_release(number3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("leaf_at_pos", [&]() {
|
||||
it("can retrieve the leaf node at a given position", [&]() {
|
||||
TSNode *number1 = ts_node_leaf_at_pos(root, 3);
|
||||
TSNode *number2 = ts_node_leaf_at_pos(root, 7);
|
||||
|
||||
AssertThat(ts_node_name(number1), Equals("number"));
|
||||
AssertThat(ts_node_size(number1), Equals<size_t>(2));
|
||||
|
||||
AssertThat(ts_node_name(number2), Equals("number"));
|
||||
AssertThat(ts_node_size(number2), Equals<size_t>(1));
|
||||
|
||||
ts_node_release(number1);
|
||||
ts_node_release(number2);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_document_free(document);
|
||||
ts_node_release(root);
|
||||
});
|
||||
|
||||
describe("child_count", [&]() {
|
||||
it("returns the number of visible child nodes", [&]() {
|
||||
AssertThat(ts_node_child_count(root), Equals<size_t>(3));
|
||||
});
|
||||
});
|
||||
|
||||
describe("child(i)", [&]() {
|
||||
it("returns the child node at the given index", [&]() {
|
||||
TSNode *number1 = ts_node_child(root, 0);
|
||||
TSNode *number2 = ts_node_child(root, 1);
|
||||
TSNode *number3 = ts_node_child(root, 2);
|
||||
|
||||
AssertThat(ts_node_name(root), Equals("array"));
|
||||
AssertThat(ts_node_name(number1), Equals("number"));
|
||||
AssertThat(ts_node_name(number2), Equals("number"));
|
||||
AssertThat(ts_node_name(number3), Equals("number"));
|
||||
|
||||
AssertThat(ts_node_pos(root), Equals<size_t>(2));
|
||||
AssertThat(ts_node_size(root), Equals<size_t>(12));
|
||||
|
||||
AssertThat(ts_node_pos(number1), Equals<size_t>(3));
|
||||
AssertThat(ts_node_size(number1), Equals<size_t>(2));
|
||||
|
||||
AssertThat(ts_node_pos(number2), Equals<size_t>(7));
|
||||
AssertThat(ts_node_size(number2), Equals<size_t>(1));
|
||||
|
||||
AssertThat(ts_node_pos(number3), Equals<size_t>(10));
|
||||
AssertThat(ts_node_size(number3), Equals<size_t>(3));
|
||||
|
||||
ts_node_release(number1);
|
||||
ts_node_release(number2);
|
||||
ts_node_release(number3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parent", [&]() {
|
||||
it("returns the node's parent node", [&]() {
|
||||
TSNode *number = ts_node_child(root, 1);
|
||||
AssertThat(ts_node_parent(number), Equals(root));
|
||||
ts_node_release(number);
|
||||
});
|
||||
});
|
||||
|
||||
describe("next_sibling and prev_sibling", [&]() {
|
||||
it("returns the node's next and previous siblings", [&]() {
|
||||
TSNode *number1 = ts_node_child(root, 0);
|
||||
TSNode *number2 = ts_node_child(root, 1);
|
||||
TSNode *number3 = ts_node_child(root, 2);
|
||||
|
||||
AssertThat(ts_node_eq(ts_node_next_sibling(number2), number3), IsTrue());
|
||||
AssertThat(ts_node_eq(ts_node_prev_sibling(number2), number1), IsTrue());
|
||||
|
||||
ts_node_release(number1);
|
||||
ts_node_release(number2);
|
||||
ts_node_release(number3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("leaf_at_pos", [&]() {
|
||||
it("can retrieve the leaf node at a given position", [&]() {
|
||||
TSNode *number1 = ts_node_leaf_at_pos(root, 3);
|
||||
TSNode *number2 = ts_node_leaf_at_pos(root, 7);
|
||||
|
||||
AssertThat(ts_node_name(number1), Equals("number"));
|
||||
AssertThat(ts_node_size(number1), Equals<size_t>(2));
|
||||
|
||||
AssertThat(ts_node_name(number2), Equals("number"));
|
||||
AssertThat(ts_node_size(number2), Equals<size_t>(1));
|
||||
|
||||
ts_node_release(number1);
|
||||
ts_node_release(number2);
|
||||
});
|
||||
|
||||
it("returns higher-level nodes when no leaf is at the given position", [&]() {
|
||||
TSNode *node = ts_node_leaf_at_pos(root, 6);
|
||||
|
||||
AssertThat(ts_node_name(node), Equals("array"));
|
||||
|
||||
ts_node_release(node);
|
||||
});
|
||||
it("returns higher-level nodes when no leaf is at the given position", [&]() {
|
||||
TSNode *node = ts_node_leaf_at_pos(root, 6);
|
||||
|
||||
AssertThat(ts_node_name(node), Equals("array"));
|
||||
|
||||
ts_node_release(node);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
|
|||
|
|
@ -10,69 +10,69 @@ TSStateId lex_fn_state_received;
|
|||
TSLexer *lex_fn_lexer_received;
|
||||
|
||||
TSTree * fake_lex(TSLexer *lexer, TSStateId state_id) {
|
||||
lex_fn_lexer_received = lexer;
|
||||
lex_fn_state_received = state_id;
|
||||
return lex_fn_node_to_return;
|
||||
lex_fn_lexer_received = lexer;
|
||||
lex_fn_state_received = state_id;
|
||||
return lex_fn_node_to_return;
|
||||
}
|
||||
|
||||
START_TEST
|
||||
|
||||
describe("LR Parsers", [&]() {
|
||||
TSParser parser;
|
||||
SpyReader *reader;
|
||||
TSLanguage language;
|
||||
TSParser parser;
|
||||
SpyReader *reader;
|
||||
TSLanguage language;
|
||||
|
||||
before_each([&]() {
|
||||
language = *dummy_language();
|
||||
language.lex_fn = fake_lex;
|
||||
parser = ts_parser_make(&language);
|
||||
|
||||
reader = new SpyReader("some structured text", 5);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_parser_destroy(&parser);
|
||||
delete reader;
|
||||
});
|
||||
|
||||
describe("when starting at the beginning of the input (edit is NULL)", [&]() {
|
||||
before_each([&]() {
|
||||
language = *dummy_language();
|
||||
language.lex_fn = fake_lex;
|
||||
parser = ts_parser_make(&language);
|
||||
|
||||
reader = new SpyReader("some structured text", 5);
|
||||
ts_parser_start(&parser, reader->input, nullptr);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_parser_destroy(&parser);
|
||||
delete reader;
|
||||
it("runs the lexer with the lex state corresponding to the initial state", [&]() {
|
||||
lex_fn_node_to_return = ts_tree_make_leaf(dummy_sym2, 5, 1, 0);
|
||||
ts_parser_step(&parser);
|
||||
AssertThat(lex_fn_state_received, Equals(100));
|
||||
});
|
||||
|
||||
describe("when starting at the beginning of the input (edit is NULL)", [&]() {
|
||||
before_each([&]() {
|
||||
ts_parser_start(&parser, reader->input, nullptr);
|
||||
});
|
||||
describe("when the returned symbol indicates a shift action", [&]() {
|
||||
before_each([&]() {
|
||||
lex_fn_node_to_return = ts_tree_make_leaf(dummy_sym2, 5, 1, 0);
|
||||
});
|
||||
|
||||
it("runs the lexer with the lex state corresponding to the initial state", [&]() {
|
||||
lex_fn_node_to_return = ts_tree_make_leaf(dummy_sym2, 5, 1, 0);
|
||||
ts_parser_step(&parser);
|
||||
AssertThat(lex_fn_state_received, Equals(100));
|
||||
});
|
||||
it("advances to the state specified in the action", [&]() {
|
||||
ts_parser_step(&parser);
|
||||
AssertThat(ts_stack_top_state(&parser.stack), Equals(12));
|
||||
});
|
||||
|
||||
describe("when the returned symbol indicates a shift action", [&]() {
|
||||
before_each([&]() {
|
||||
lex_fn_node_to_return = ts_tree_make_leaf(dummy_sym2, 5, 1, 0);
|
||||
});
|
||||
|
||||
it("advances to the state specified in the action", [&]() {
|
||||
ts_parser_step(&parser);
|
||||
AssertThat(ts_stack_top_state(&parser.stack), Equals(12));
|
||||
});
|
||||
|
||||
it("continues parsing (returns NULL)", [&]() {
|
||||
auto result = ts_parser_step(&parser);
|
||||
AssertThat(result, Equals((TSTree *)nullptr));
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the returned symbol indicates an error", [&]() {
|
||||
before_each([&]() {
|
||||
lex_fn_node_to_return = ts_tree_make_leaf(dummy_sym1, 5, 1, 0);
|
||||
});
|
||||
|
||||
it("ends the parse, returning an error tree", [&]() {
|
||||
auto result = ts_parser_step(&parser);
|
||||
AssertThat(result->symbol, Equals(ts_builtin_sym_error));
|
||||
});
|
||||
});
|
||||
it("continues parsing (returns NULL)", [&]() {
|
||||
auto result = ts_parser_step(&parser);
|
||||
AssertThat(result, Equals((TSTree *)nullptr));
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the returned symbol indicates an error", [&]() {
|
||||
before_each([&]() {
|
||||
lex_fn_node_to_return = ts_tree_make_leaf(dummy_sym1, 5, 1, 0);
|
||||
});
|
||||
|
||||
it("ends the parse, returning an error tree", [&]() {
|
||||
auto result = ts_parser_step(&parser);
|
||||
AssertThat(result->symbol, Equals(ts_builtin_sym_error));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "runtime/runtime_spec_helper.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
return bandit::run(argc, argv);
|
||||
return bandit::run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,89 +8,89 @@ enum { sym1, sym2, hidden_sym };
|
|||
int hidden_symbols[] = { 0, 0, 1 };
|
||||
|
||||
describe("stacks", [&]() {
|
||||
TSStack stack;
|
||||
TSStack stack;
|
||||
|
||||
before_each([&]() {
|
||||
stack = ts_stack_make();
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_stack_delete(&stack);
|
||||
});
|
||||
|
||||
it("starts out empty", [&]() {
|
||||
AssertThat(stack.size, Equals<size_t>(0));
|
||||
AssertThat(ts_stack_top_state(&stack), Equals(0));
|
||||
AssertThat(ts_stack_top_node(&stack), Equals((TSTree *)nullptr));
|
||||
});
|
||||
|
||||
describe("pushing a symbol", [&]() {
|
||||
TSTree *node1;
|
||||
|
||||
before_each([&]() {
|
||||
stack = ts_stack_make();
|
||||
node1 = ts_tree_make_leaf(sym1, 5, 1, 0);
|
||||
ts_stack_push(&stack, 5, node1);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_stack_delete(&stack);
|
||||
ts_tree_release(node1);
|
||||
});
|
||||
|
||||
it("starts out empty", [&]() {
|
||||
AssertThat(stack.size, Equals<size_t>(0));
|
||||
AssertThat(ts_stack_top_state(&stack), Equals(0));
|
||||
AssertThat(ts_stack_top_node(&stack), Equals((TSTree *)nullptr));
|
||||
it("adds the symbol to the stack", [&]() {
|
||||
AssertThat(stack.size, Equals<size_t>(1));
|
||||
AssertThat(ts_stack_top_state(&stack), Equals(5));
|
||||
AssertThat(ts_stack_top_node(&stack), Equals(node1));
|
||||
});
|
||||
});
|
||||
|
||||
describe("reducing a symbol", [&]() {
|
||||
TSTree **nodes;
|
||||
|
||||
before_each([&]() {
|
||||
nodes = tree_array({
|
||||
ts_tree_make_leaf(sym1, 5, 1, 0),
|
||||
ts_tree_make_leaf(sym1, 5, 1, 0),
|
||||
ts_tree_make_leaf(hidden_sym, 5, 1, 0),
|
||||
ts_tree_make_leaf(sym1, 5, 1, 0),
|
||||
});
|
||||
|
||||
for (TSStateId i = 0; i < 4; i++)
|
||||
ts_stack_push(&stack, 10 + i, nodes[i]);
|
||||
});
|
||||
|
||||
describe("pushing a symbol", [&]() {
|
||||
TSTree *node1;
|
||||
|
||||
before_each([&]() {
|
||||
node1 = ts_tree_make_leaf(sym1, 5, 1, 0);
|
||||
ts_stack_push(&stack, 5, node1);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_tree_release(node1);
|
||||
});
|
||||
|
||||
it("adds the symbol to the stack", [&]() {
|
||||
AssertThat(stack.size, Equals<size_t>(1));
|
||||
AssertThat(ts_stack_top_state(&stack), Equals(5));
|
||||
AssertThat(ts_stack_top_node(&stack), Equals(node1));
|
||||
});
|
||||
after_each([&]() {
|
||||
for (TSStateId i = 0; i < 4; i++)
|
||||
ts_tree_release(nodes[i]);
|
||||
free(nodes);
|
||||
});
|
||||
|
||||
describe("reducing a symbol", [&]() {
|
||||
TSTree **nodes;
|
||||
|
||||
before_each([&]() {
|
||||
nodes = tree_array({
|
||||
ts_tree_make_leaf(sym1, 5, 1, 0),
|
||||
ts_tree_make_leaf(sym1, 5, 1, 0),
|
||||
ts_tree_make_leaf(hidden_sym, 5, 1, 0),
|
||||
ts_tree_make_leaf(sym1, 5, 1, 0),
|
||||
});
|
||||
|
||||
for (TSStateId i = 0; i < 4; i++)
|
||||
ts_stack_push(&stack, 10 + i, nodes[i]);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
for (TSStateId i = 0; i < 4; i++)
|
||||
ts_tree_release(nodes[i]);
|
||||
free(nodes);
|
||||
});
|
||||
|
||||
it("pops the given number of nodes off the stack", [&]() {
|
||||
AssertThat(stack.size, Equals<size_t>(4));
|
||||
ts_stack_reduce(&stack, sym2, 3, hidden_symbols, 0);
|
||||
AssertThat(stack.size, Equals<size_t>(1));
|
||||
});
|
||||
|
||||
it("returns a node with the given symbol", [&]() {
|
||||
TSTree *node = ts_stack_reduce(&stack, sym2, 3, hidden_symbols, 0);
|
||||
AssertThat(node->symbol, Equals(sym2));
|
||||
});
|
||||
|
||||
it("removes any hidden nodes from its regular list of children", [&]() {
|
||||
TSTree *expected_children[3] = {
|
||||
stack.entries[1].node,
|
||||
stack.entries[2].node,
|
||||
stack.entries[3].node,
|
||||
};
|
||||
|
||||
TSTree *node = ts_stack_reduce(&stack, sym2, 3, hidden_symbols, 0);
|
||||
size_t child_count;
|
||||
TSTree **children = ts_tree_children(node, &child_count);
|
||||
|
||||
AssertThat(child_count, Equals<size_t>(3));
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
AssertThat(children[i], Equals(expected_children[i]));
|
||||
});
|
||||
it("pops the given number of nodes off the stack", [&]() {
|
||||
AssertThat(stack.size, Equals<size_t>(4));
|
||||
ts_stack_reduce(&stack, sym2, 3, hidden_symbols, 0);
|
||||
AssertThat(stack.size, Equals<size_t>(1));
|
||||
});
|
||||
|
||||
it("returns a node with the given symbol", [&]() {
|
||||
TSTree *node = ts_stack_reduce(&stack, sym2, 3, hidden_symbols, 0);
|
||||
AssertThat(node->symbol, Equals(sym2));
|
||||
});
|
||||
|
||||
it("removes any hidden nodes from its regular list of children", [&]() {
|
||||
TSTree *expected_children[3] = {
|
||||
stack.entries[1].node,
|
||||
stack.entries[2].node,
|
||||
stack.entries[3].node,
|
||||
};
|
||||
|
||||
TSTree *node = ts_stack_reduce(&stack, sym2, 3, hidden_symbols, 0);
|
||||
size_t child_count;
|
||||
TSTree **children = ts_tree_children(node, &child_count);
|
||||
|
||||
AssertThat(child_count, Equals<size_t>(3));
|
||||
for (size_t i = 0; i < 2; i++)
|
||||
AssertThat(children[i], Equals(expected_children[i]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
|
|||
|
|
@ -12,80 +12,80 @@ enum {
|
|||
static const char *names[] = { "error", "end", "cat", "dog", "pig" };
|
||||
|
||||
describe("trees", []() {
|
||||
TSTree *tree1, *tree2, *parent1;
|
||||
TSTree *tree1, *tree2, *parent1;
|
||||
|
||||
before_each([&]() {
|
||||
tree1 = ts_tree_make_leaf(cat, 5, 2, 0);
|
||||
tree2 = ts_tree_make_leaf(cat, 3, 1, 0);
|
||||
parent1 = ts_tree_make_node(dog, 2, tree_array({
|
||||
tree1, tree2, // children
|
||||
}), 0);
|
||||
before_each([&]() {
|
||||
tree1 = ts_tree_make_leaf(cat, 5, 2, 0);
|
||||
tree2 = ts_tree_make_leaf(cat, 3, 1, 0);
|
||||
parent1 = ts_tree_make_node(dog, 2, tree_array({
|
||||
tree1, tree2, // children
|
||||
}), 0);
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_tree_release(tree1);
|
||||
ts_tree_release(tree2);
|
||||
ts_tree_release(parent1);
|
||||
});
|
||||
|
||||
describe("making a parent node", [&]() {
|
||||
it("computes its size based on its child nodes", [&]() {
|
||||
AssertThat(parent1->size, Equals<size_t>(9));
|
||||
});
|
||||
|
||||
after_each([&]() {
|
||||
ts_tree_release(tree1);
|
||||
ts_tree_release(tree2);
|
||||
ts_tree_release(parent1);
|
||||
it("computes its offset based on its first child", [&]() {
|
||||
AssertThat(parent1->offset, Equals<size_t>(2));
|
||||
});
|
||||
});
|
||||
|
||||
describe("equality", [&]() {
|
||||
it("returns true for identical trees", [&]() {
|
||||
TSTree *tree1_copy = ts_tree_make_leaf(cat, 5, 2, 0);
|
||||
AssertThat(ts_tree_equals(tree1, tree1_copy), Equals(1));
|
||||
TSTree *tree2_copy = ts_tree_make_leaf(cat, 3, 1, 0);
|
||||
AssertThat(ts_tree_equals(tree2, tree2_copy), Equals(1));
|
||||
|
||||
TSTree *parent2 = ts_tree_make_node(dog, 2, tree_array({
|
||||
tree1_copy, tree2_copy,
|
||||
}), 0);
|
||||
AssertThat(ts_tree_equals(parent1, parent2), Equals(1));
|
||||
|
||||
ts_tree_release(tree1_copy);
|
||||
ts_tree_release(tree2_copy);
|
||||
ts_tree_release(parent2);
|
||||
});
|
||||
|
||||
describe("making a parent node", [&]() {
|
||||
it("computes its size based on its child nodes", [&]() {
|
||||
AssertThat(parent1->size, Equals<size_t>(9));
|
||||
});
|
||||
|
||||
it("computes its offset based on its first child", [&]() {
|
||||
AssertThat(parent1->offset, Equals<size_t>(2));
|
||||
});
|
||||
it("returns false for trees with different symbols", [&]() {
|
||||
TSTree *different_tree = ts_tree_make_leaf(pig, 0, 0, 0);
|
||||
AssertThat(ts_tree_equals(tree1, different_tree), Equals(0));
|
||||
ts_tree_release(different_tree);
|
||||
});
|
||||
|
||||
describe("equality", [&]() {
|
||||
it("returns true for identical trees", [&]() {
|
||||
TSTree *tree1_copy = ts_tree_make_leaf(cat, 5, 2, 0);
|
||||
AssertThat(ts_tree_equals(tree1, tree1_copy), Equals(1));
|
||||
TSTree *tree2_copy = ts_tree_make_leaf(cat, 3, 1, 0);
|
||||
AssertThat(ts_tree_equals(tree2, tree2_copy), Equals(1));
|
||||
it("returns false for trees with different children", [&]() {
|
||||
TSTree *different_tree = ts_tree_make_leaf(pig, 0, 0, 0);
|
||||
TSTree *different_parent = ts_tree_make_node(dog, 2, tree_array({
|
||||
different_tree, different_tree,
|
||||
}), 0);
|
||||
|
||||
TSTree *parent2 = ts_tree_make_node(dog, 2, tree_array({
|
||||
tree1_copy, tree2_copy,
|
||||
}), 0);
|
||||
AssertThat(ts_tree_equals(parent1, parent2), Equals(1));
|
||||
AssertThat(ts_tree_equals(different_parent, parent1), Equals(0));
|
||||
AssertThat(ts_tree_equals(parent1, different_parent), Equals(0));
|
||||
|
||||
ts_tree_release(tree1_copy);
|
||||
ts_tree_release(tree2_copy);
|
||||
ts_tree_release(parent2);
|
||||
});
|
||||
|
||||
it("returns false for trees with different symbols", [&]() {
|
||||
TSTree *different_tree = ts_tree_make_leaf(pig, 0, 0, 0);
|
||||
AssertThat(ts_tree_equals(tree1, different_tree), Equals(0));
|
||||
ts_tree_release(different_tree);
|
||||
});
|
||||
|
||||
it("returns false for trees with different children", [&]() {
|
||||
TSTree *different_tree = ts_tree_make_leaf(pig, 0, 0, 0);
|
||||
TSTree *different_parent = ts_tree_make_node(dog, 2, tree_array({
|
||||
different_tree, different_tree,
|
||||
}), 0);
|
||||
|
||||
AssertThat(ts_tree_equals(different_parent, parent1), Equals(0));
|
||||
AssertThat(ts_tree_equals(parent1, different_parent), Equals(0));
|
||||
|
||||
ts_tree_release(different_tree);
|
||||
ts_tree_release(different_parent);
|
||||
});
|
||||
ts_tree_release(different_tree);
|
||||
ts_tree_release(different_parent);
|
||||
});
|
||||
});
|
||||
|
||||
describe("serialization", [&]() {
|
||||
it("returns a readable string", [&]() {
|
||||
auto string1 = ts_tree_string(tree1, names);
|
||||
AssertThat(string(string1), Equals("(cat)"));
|
||||
free(string1);
|
||||
describe("serialization", [&]() {
|
||||
it("returns a readable string", [&]() {
|
||||
auto string1 = ts_tree_string(tree1, names);
|
||||
AssertThat(string(string1), Equals("(cat)"));
|
||||
free(string1);
|
||||
|
||||
auto string2 = ts_tree_string(parent1, names);
|
||||
AssertThat(string(string2), Equals("(dog (cat) (cat))"));
|
||||
free(string2);
|
||||
});
|
||||
auto string2 = ts_tree_string(parent1, names);
|
||||
AssertThat(string(string2), Equals("(dog (cat) (cat))"));
|
||||
free(string2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
END_TEST
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue