Rather than letting the reduced tree become the new lookahead symbol, and re-adding it to the stack via a subsequent shift action, just add it to the stack as part of the reduce action. This is more in line with the way LR is described traditionally.
113 lines
3.3 KiB
C++
113 lines
3.3 KiB
C++
#include "runtime/debugger.h"
|
|
#include "runtime/helpers/spy_debugger.h"
|
|
#include "runtime/runtime_spec_helper.h"
|
|
|
|
extern "C" const TSLanguage * ts_language_json();
|
|
|
|
START_TEST
|
|
|
|
describe("Document", [&]() {
|
|
TSDocument *doc;
|
|
|
|
before_each([&]() {
|
|
doc = ts_document_make();
|
|
});
|
|
|
|
after_each([&]() {
|
|
ts_document_free(doc);
|
|
});
|
|
|
|
describe("set_input(TSInput)", [&]() {
|
|
describe("when the language is set", [&]() {
|
|
before_each([&]() {
|
|
ts_document_set_language(doc, ts_language_json());
|
|
});
|
|
|
|
it("parses the document", [&]() {
|
|
ts_document_set_input_string(doc, "{ \"key\": [1, 2] }");
|
|
|
|
AssertThat(ts_node_string(ts_document_root_node(doc)), Equals(
|
|
"(DOCUMENT (object (string) (array (number) (number))))"));
|
|
});
|
|
});
|
|
|
|
describe("when the language is not set", [&]() {
|
|
it("does not try to parse the document", [&]() {
|
|
ts_document_set_input_string(doc, "{ \"key\": [1, 2] }");
|
|
|
|
AssertThat(ts_document_root_node(doc), Equals<TSNode *>(nullptr));
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("set_language(TSLanguage)", [&]() {
|
|
describe("when the input is not set", [&]() {
|
|
it("does not try to parse the document", [&]() {
|
|
ts_document_set_language(doc, ts_language_json());
|
|
|
|
AssertThat(ts_document_root_node(doc), Equals<TSNode *>(nullptr));
|
|
});
|
|
});
|
|
|
|
describe("when the input is set", [&]() {
|
|
before_each([&]() {
|
|
ts_document_set_input_string(doc, "{ \"key\": [1, 2] }");
|
|
});
|
|
|
|
it("parses the document", [&]() {
|
|
ts_document_set_language(doc, ts_language_json());
|
|
|
|
AssertThat(ts_node_string(ts_document_root_node(doc)), Equals(
|
|
"(DOCUMENT (object (string) (array (number) (number))))"));
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("set_debugger(TSDebugger)", [&]() {
|
|
SpyDebugger *debugger;
|
|
|
|
before_each([&]() {
|
|
debugger = new SpyDebugger();
|
|
ts_document_set_language(doc, ts_language_json());
|
|
ts_document_set_debugger(doc, debugger->debugger());
|
|
});
|
|
|
|
it("calls the debugger with a message for each lex action", [&]() {
|
|
ts_document_set_input_string(doc, "[1, 2]");
|
|
|
|
AssertThat(debugger->messages, Contains("lookahead char:'1'"));
|
|
AssertThat(debugger->messages, Contains("advance state:1"));
|
|
AssertThat(debugger->messages, Contains("accept_token sym:number"));
|
|
});
|
|
|
|
it("calls the debugger with a message for each parse action", [&]() {
|
|
ts_document_set_input_string(doc, "[1, 2]");
|
|
|
|
AssertThat(debugger->messages, Contains("new_parse"));
|
|
AssertThat(debugger->messages, Contains("lookahead char:'['"));
|
|
AssertThat(debugger->messages, Contains("reduce sym:value, count:1"));
|
|
AssertThat(debugger->messages, Contains("accept"));
|
|
});
|
|
|
|
it("allows the debugger to be retrieved later", [&]() {
|
|
AssertThat(ts_document_get_debugger(doc).data, Equals(debugger));
|
|
});
|
|
|
|
describe("disabling debugging", [&]() {
|
|
before_each([&]() {
|
|
ts_document_set_debugger(doc, ts_debugger_null());
|
|
});
|
|
|
|
it("does not call the debugger any more", [&]() {
|
|
ts_document_set_input_string(doc, "[1, 2]");
|
|
AssertThat(debugger->messages, IsEmpty());
|
|
});
|
|
|
|
it("releases the old debugger", [&]() {
|
|
AssertThat(debugger->release_call_count, Equals<size_t>(1));
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
END_TEST
|