Clean up the reader's test cases

This commit is contained in:
Sameer Rahmani 2022-03-08 14:20:15 +00:00
parent d52b2bedd2
commit df2300498b
3 changed files with 40 additions and 27 deletions

View File

@ -126,7 +126,7 @@ functions and detect hot functions similar to how javascript jits do it
and recompile those functions with more optimization passes and recompile those functions with more optimization passes
* TODOs * TODOs
** TODO Create =Catch2= generators to be used in tests. Specially for the =reader= tests
** TODO Investigate possible implementanion for Internal Errors ** TODO Investigate possible implementanion for Internal Errors
- An option is to use llvm registry functionality like the one used in =clang-doc= instead of - An option is to use llvm registry functionality like the one used in =clang-doc= instead of
=errorVariants= var. =errorVariants= var.

View File

@ -44,6 +44,7 @@
#include "serene/reader/location.h" #include "serene/reader/location.h"
#include "serene/serene.h" #include "serene/serene.h"
#include <serene/export.h>
#include <system_error> #include <system_error>
#include <llvm/Support/Debug.h> #include <llvm/Support/Debug.h>
@ -124,12 +125,13 @@ public:
/// Parses the given `input` string and returns a `Result<ast>` /// Parses the given `input` string and returns a `Result<ast>`
/// which may contains an AST or an `llvm::Error` /// which may contains an AST or an `llvm::Error`
exprs::MaybeAst read(SereneContext &ctx, llvm::StringRef input, SERENE_EXPORT exprs::MaybeAst read(SereneContext &ctx, llvm::StringRef input,
llvm::StringRef ns, llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename); llvm::Optional<llvm::StringRef> filename);
exprs::MaybeAst read(SereneContext &ctx, llvm::MemoryBufferRef input, SERENE_EXPORT exprs::MaybeAst read(SereneContext &ctx,
llvm::StringRef ns, llvm::MemoryBufferRef input,
llvm::Optional<llvm::StringRef> filename); llvm::StringRef ns,
llvm::Optional<llvm::StringRef> filename);
} // namespace serene::reader } // namespace serene::reader
#endif #endif

View File

@ -16,88 +16,99 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef SERENE_TEST_READER_H
#define SERENE_TEST_READER_H
#include "serene/reader/reader.h" #include "serene/reader/reader.h"
#include "../test_helpers.cpp.inc" #include <catch2/catch_test_macros.hpp>
#include <catch2/catch_all.hpp>
// *IMPORTANT NOTE:* The `READ` macro is just a quick way to eliminate
// the overhead of writing the same function signature
// over and over again. Nothing special about it.
#define READ(input) reader::read(*ctx, input, "user", llvm::None)
namespace serene { namespace serene {
namespace reader { namespace reader {
TEST_CASE("Read numbers", "[reader]") { TEST_CASE("Read numbers", "[reader]") {
auto maybeAst = reader::read("3"); auto ctx = makeSereneContext();
auto maybeAst = READ("3");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
auto ast = std::move(maybeAst).getValue(); auto ast = *maybeAst;
REQUIRE_FALSE(ast.empty()); REQUIRE_FALSE(ast.empty());
CHECK(ast.front()->toString() == "<Number 3>"); CHECK(ast.front()->toString() == "<Number 3>");
maybeAst = reader::read("-34"); maybeAst = READ("-34");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
ast = std::move(maybeAst.getValue()); ast = *maybeAst;
REQUIRE_FALSE(ast.empty()); REQUIRE_FALSE(ast.empty());
CHECK(ast.front()->toString() == "<Number -34>"); CHECK(ast.front()->toString() == "<Number -34>");
maybeAst = reader::read("-3.5434"); maybeAst = READ("-3.5434");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
ast = std::move(maybeAst.getValue()); ast = *maybeAst;
REQUIRE_FALSE(ast.empty()); REQUIRE_FALSE(ast.empty());
CHECK(ast.front()->toString() == "<Number -3.5434>"); CHECK(ast.front()->toString() == "<Number -3.5434>");
maybeAst = reader::read("444323 2123 123123"); maybeAst = READ("444323 2123 123123");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
ast = std::move(maybeAst.getValue()); ast = *maybeAst;
REQUIRE(ast.size() == 3); REQUIRE(ast.size() == 3);
CHECK(ast.front()->toString() == "<Number 444323>"); CHECK(ast.front()->toString() == "<Number 444323>");
CHECK(ast[1]->toString() == "<Number 2123>"); CHECK(ast[1]->toString() == "<Number 2123>");
CHECK(ast[2]->toString() == "<Number 123123>"); CHECK(ast[2]->toString() == "<Number 123123>");
}; };
TEST_CASE("Read Lists and Symbols", "[reader]") { TEST_CASE("Read Lists and Symbols", "[reader]") {
auto maybeAst = reader::read("(x 1)"); auto ctx = makeSereneContext();
auto maybeAst = READ("(x 1)");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
auto ast = std::move(maybeAst.getValue()); auto ast = *maybeAst;
REQUIRE_FALSE(ast.empty()); REQUIRE_FALSE(ast.empty());
CHECK(ast.front()->toString() == "<List <Symbol x> <Number 1>>"); CHECK(ast.front()->toString() == "<List <Symbol user/x> <Number 1>>");
maybeAst = reader::read("(x (y (z)))"); maybeAst = READ("(x (y (z)))");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
ast = std::move(maybeAst.getValue()); ast = *maybeAst;
REQUIRE_FALSE(ast.empty()); REQUIRE_FALSE(ast.empty());
CHECK(ast.front()->toString() == CHECK(ast.front()->toString() == "<List <Symbol user/x> <List <Symbol "
"<List <Symbol x> <List <Symbol y> <List <Symbol z>>>>"); "user/y> <List <Symbol user/z>>>>");
maybeAst = reader::read("(x \n y)"); maybeAst = READ("(x \n y)");
if (!maybeAst) { if (!maybeAst) {
FAIL(); FAIL();
} }
ast = std::move(maybeAst.getValue()); ast = *maybeAst;
REQUIRE_FALSE(ast.empty()); REQUIRE_FALSE(ast.empty());
CHECK(ast.front()->toString() == "<List <Symbol x> <Symbol y>>"); CHECK(ast.front()->toString() == "<List <Symbol user/x> <Symbol user/y>>");
}; };
} // namespace reader } // namespace reader
} // namespace serene } // namespace serene
#endif