tree-sitter/spec/compiler/build_tables/rule_transitions_spec.cpp

187 lines
5.5 KiB
C++
Raw Normal View History

2013-12-28 23:26:20 -08:00
#include "spec_helper.h"
2014-02-18 09:07:00 -08:00
#include "build_tables/rule_transitions.h"
2014-01-11 15:14:17 -08:00
2014-01-11 17:08:32 -08:00
using namespace rules;
using namespace build_tables;
2013-12-28 23:26:20 -08:00
2014-02-11 13:15:44 -08:00
template<typename K>
class rule_map : public map<K, rule_ptr> {
public:
bool operator==(const map<K, rule_ptr> &other) const {
if (this->size() != other.size()) return false;
for (const auto &pair : *this) {
auto other_pair = other.find(pair.first);
if (other_pair == other.end()) return false;
if (!pair.second->operator==(*other_pair->second)) return false;
}
return true;
}
rule_map(const initializer_list<pair<const K, rule_ptr>> &list) : map<K, rule_ptr>(list) {}
};
2013-12-28 23:26:20 -08:00
START_TEST
describe("rule transitions", []() {
it("handles symbols", [&]() {
AssertThat(
2014-02-11 13:15:44 -08:00
sym_transitions(sym("1")),
Equals(rule_map<Symbol>({
{ Symbol("1"), blank() }
2013-12-28 23:26:20 -08:00
})));
});
it("handles choices", [&]() {
AssertThat(
2014-02-11 13:15:44 -08:00
sym_transitions(choice({ sym("1"), sym("2") })),
Equals(rule_map<Symbol>({
{ Symbol("1"), blank() },
{ Symbol("2"), blank() }
})));
});
2013-12-28 23:26:20 -08:00
it("handles sequences", [&]() {
AssertThat(
2014-02-11 13:15:44 -08:00
sym_transitions(seq({ sym("1"), sym("2") })),
Equals(rule_map<Symbol>({
{ Symbol("1"), sym("2") }
2013-12-28 23:26:20 -08:00
})));
});
it("handles long sequences", [&]() {
2013-12-28 23:26:20 -08:00
AssertThat(
sym_transitions(seq({
2014-02-11 13:15:44 -08:00
sym("1"),
sym("2"),
sym("3"),
sym("4")
2013-12-28 23:26:20 -08:00
})),
2014-02-11 13:15:44 -08:00
Equals(rule_map<Symbol>({
{ Symbol("1"), seq({ sym("2"), sym("3"), sym("4") }) }
2013-12-28 23:26:20 -08:00
})));
});
it("handles sequences whose left sides can be blank", [&]() {
AssertThat(
sym_transitions(seq({
choice({
2014-02-11 13:15:44 -08:00
sym("1"),
blank(),
}),
seq({
2014-02-11 13:15:44 -08:00
sym("1"),
sym("2")
})
2014-02-11 13:15:44 -08:00
})), Equals(rule_map<Symbol>({
{ Symbol("1"), choice({ seq({ sym("1"), sym("2") }), sym("2"), }) }
})));
});
2013-12-28 23:26:20 -08:00
it("handles choices with common starting symbols", [&]() {
AssertThat(
sym_transitions(
2014-01-11 17:08:32 -08:00
choice({
2014-02-11 13:15:44 -08:00
seq({ sym("1"), sym("2") }),
seq({ sym("1"), sym("3") }) })),
Equals(rule_map<Symbol>({
{ Symbol("1"), choice({ sym("2"), sym("3") }) }
2013-12-28 23:26:20 -08:00
})));
});
it("handles characters", [&]() {
AssertThat(
char_transitions(character({ '1' })),
2014-02-11 13:15:44 -08:00
Equals(rule_map<CharacterSet>({
{ CharacterSet({ '1' }), blank() }
})));
});
2013-12-28 23:26:20 -08:00
it("handles strings", [&]() {
AssertThat(
char_transitions(str("bad")),
2014-02-11 13:15:44 -08:00
Equals(rule_map<CharacterSet>({
{ CharacterSet({ 'b' }), seq({ character({ 'a' }), character({ 'd' }) }) }
})));
2013-12-28 23:26:20 -08:00
});
it("handles patterns", [&]() {
AssertThat(
char_transitions(pattern("a|b")),
2014-02-11 13:15:44 -08:00
Equals(rule_map<CharacterSet>({
{ CharacterSet({ 'a' }), blank() },
{ CharacterSet({ 'b' }), blank() }
2013-12-28 23:26:20 -08:00
})));
});
2014-02-11 13:15:44 -08:00
it("handles choices between overlapping character sets", [&]() {
AssertThat(
char_transitions(choice({
seq({
character({ {'a', 's'} }),
sym("x") }),
seq({
character({ { 'm', 'z' } }),
sym("y") }) })),
Equals(rule_map<CharacterSet>({
{ CharacterSet({ {'a','l'} }), sym("x") },
{ CharacterSet({ {'m','s'} }), choice({ sym("x"), sym("y") }) },
{ CharacterSet({ {'t','z'} }), sym("y") },
2014-02-11 13:15:44 -08:00
})));
});
2013-12-28 23:26:20 -08:00
it("handles repeats", [&]() {
2014-01-11 17:08:32 -08:00
rule_ptr rule = repeat(str("ab"));
2013-12-28 23:26:20 -08:00
AssertThat(
char_transitions(rule),
2014-02-11 13:15:44 -08:00
Equals(rule_map<CharacterSet>({
{
CharacterSet({ 'a' }),
seq({
character({ 'b' }),
2014-02-11 13:15:44 -08:00
choice({
rule,
blank()
})
2013-12-28 23:26:20 -08:00
})
2014-02-11 13:15:44 -08:00
}})));
2013-12-28 23:26:20 -08:00
2014-01-11 17:08:32 -08:00
rule = repeat(str("a"));
2013-12-28 23:26:20 -08:00
AssertThat(
char_transitions(rule),
2014-02-11 13:15:44 -08:00
Equals(rule_map<CharacterSet>({
2013-12-28 23:26:20 -08:00
{
2014-02-11 13:15:44 -08:00
CharacterSet({ 'a' }),
2014-01-11 17:08:32 -08:00
choice({
rule,
blank()
2013-12-28 23:26:20 -08:00
})
}})));
});
2014-01-30 13:04:10 -08:00
describe("regression tests (somewhat redundant, should maybe be deleted later)", []() {
it("handles sequences that start with repeating characters", [&]() {
auto rule = seq({
choice({
repeat(character({ '"' }, false)),
blank(),
}),
character({ '"' }),
2014-01-30 13:04:10 -08:00
});
2014-02-11 13:15:44 -08:00
AssertThat(char_transitions(rule), Equals(rule_map<CharacterSet>({
{ CharacterSet({ '"' }).complement(), seq({
2014-01-30 13:04:10 -08:00
choice({
repeat(character({ '"' }, false)),
blank(),
}),
character({ '"' }), }) },
{ CharacterSet({ '"' }), blank() },
2014-01-30 13:04:10 -08:00
})));
});
});
2013-12-28 23:26:20 -08:00
});
2013-12-28 23:26:20 -08:00
END_TEST