Create new categorized test classes, for the most part just a copy of current tests into new framework

This commit is contained in:
Tyler Wilding
2020-10-08 00:06:48 -04:00
parent 097a9157f5
commit df6e6dd2a2
21 changed files with 1222 additions and 397 deletions
+17 -17
View File
@@ -1,22 +1,22 @@
include("goalc/CMakeLists.txt")
add_executable(goalc-test
test_main.cpp
#test_test.cpp
#test_reader.cpp
#test_goos.cpp
#test_listener_deci2.cpp
#test_kernel.cpp
#all_jak1_symbols.cpp
#test_type_system.cpp
#test_CodeTester.cpp
#test_emitter_slow.cpp
#test_emitter_loads_and_store.cpp
#test_emitter_xmm32.cpp
#test_emitter_integer_math.cpp
#test_common_util.cpp
#test_compiler_and_runtime.cpp
"goalc/test_compiler_integer.cpp"
"goalc/framework/test_runner.cpp"
"goalc/framework/test_runner.h")
test_test.cpp
test_reader.cpp
test_goos.cpp
test_listener_deci2.cpp
test_kernel.cpp
all_jak1_symbols.cpp
test_type_system.cpp
test_CodeTester.cpp
test_emitter_slow.cpp
test_emitter_loads_and_store.cpp
test_emitter_xmm32.cpp
test_emitter_integer_math.cpp
test_common_util.cpp
${GOALC_TEST_FRAMEWORK_SOURCES}
${GOALC_TEST_CASES})
enable_testing()
+24
View File
@@ -0,0 +1,24 @@
# TODO - probably a more cmakey way to do this
set(GOALC_TEST_CASES
"goalc/test_arithmetic.cpp"
"goalc/test_control_statements.cpp"
"goalc/test_collections.cpp"
"goalc/test_float.cpp"
"goalc/test_functions.cpp"
"goalc/test_library.cpp"
"goalc/test_logic.cpp"
"goalc/test_loop_recur.cpp"
"goalc/test_macros.cpp"
"goalc/test_methods.cpp"
"goalc/test_pointers.cpp"
"goalc/test_strings.cpp"
"goalc/test_symbols.cpp"
"goalc/test_variables.cpp"
"goalc/test_with_game.cpp"
)
set(GOALC_TEST_FRAMEWORK_SOURCES
"goalc/framework/test_runner.cpp"
"goalc/framework/test_runner.h"
)
+6 -10
View File
@@ -1,12 +1,8 @@
Goal:
# Some Documentation
Create a flexible test framework for testing GOAL code:
- pass in templated GOAL files to easily test many/large cases of tests
- probably need macros / helper functions around things like:
- generating math expressions in post-fix (we need to know the result to assert it)
- if a test fails, need to print out the code / save it to a file so it can be inspected
TODO!
The real selling point is being able to three-fold:
- Reduce the number of compiler test files, while still maintaining the same test-coverage
- Easily create stressful tests for the compiler, make test combinations
- Have the expected test result in the same place as the test code, no need to cross-reference .gc file
# TODO
- If it can't make the file successfully, currently the tests just hang
- How do i share the same fixture (compiler/thread instance), but with different Params. I don't think this is possible...maybe with templates?
+38 -45
View File
@@ -12,6 +12,7 @@
#include "goalc/compiler/Compiler.h"
#include "common\util\FileUtil.h"
#include <filesystem>
namespace GoalTest {
@@ -32,24 +33,35 @@ std::string escaped_string(const std::string& in) {
return result;
}
void CompilerTestRunner::run_test(const std::string& test_file,
void CompilerTestRunner::run_static_test(inja::Environment& env,
std::string& testCategory,
const std::string& test_file,
const std::vector<std::string>& expected,
MatchParam<int> truncate) {
env.write(test_file, {}, test_file);
run_test(testCategory, test_file, expected, truncate);
}
void CompilerTestRunner::run_test(const std::string& test_category,
const std::string& test_file,
const std::vector<std::string>& expected,
MatchParam<int> truncate) {
fprintf(stderr, "Testing %s\n", test_file.c_str());
auto result = c->run_test("test/goalc/source_generated/" + test_file);
auto result = c->run_test("test/goalc/source_generated/" + test_category + "/" + test_file);
if (!truncate.is_wildcard) {
for (auto& x : result) {
x = x.substr(0, truncate.value);
}
}
EXPECT_EQ(result, expected);
bool assertionFailed = false;
EXPECT_EQ(result, expected) << (assertionFailed = true);
if (testing::Test::HasFailure()) {
std::string testFile = file_util::get_file_path({"test/goalc/source_generated/" + test_file});
// TODO - put the expected and unexpected values as comments in the file as well
std::string failedFile =
file_util::get_file_path({"test/goalc/source_generated/failed/" + test_file});
if (assertionFailed) {
std::string testFile = GoalTest::getGeneratedDir(test_category) + test_file;
std::string failedFile = GoalTest::getFailedDir(test_category) + test_file;
GoalTest::createDirIfAbsent(GoalTest::getFailedDir(test_category));
std::ifstream src(testFile, std::ios::binary);
std::ofstream dst(failedFile, std::ios::binary);
@@ -70,46 +82,12 @@ void CompilerTestRunner::run_test(const std::string& test_file,
tests.push_back({expected, result, test_file, false});
}
void CompilerTestRunner::run_always_pass(const std::string& test_file) {
c->run_test("test/goalc/source_generated/" + test_file);
void CompilerTestRunner::run_always_pass(const std::string& test_category,
const std::string& test_file) {
c->run_test("test/goalc/source_generated/" + test_category + "/" + test_file);
tests.push_back({{}, {}, test_file, true});
}
// TODO - This might not be necessary with the switch to parameterized tests
void CompilerTestRunner::print_summary() {
fmt::print("~~ Compiler Test Summary for {} tests... ~~\n", tests.size());
int passed = 0;
int passable = 0;
int auto_pass = 0;
for (auto& test : tests) {
if (test.auto_pass) {
auto_pass++;
fmt::print("[{:40}] AUTO-PASS!\n", test.test_name);
} else {
passable++;
if (test.expected == test.actual) {
fmt::print("[{:40}] PASS!\n", test.test_name);
passed++;
} else {
fmt::print("[{:40}] FAIL!\n", test.test_name);
fmt::print("expected:\n");
for (auto& x : test.expected) {
fmt::print(" \"{}\"\n", escaped_string(x));
}
fmt::print("result:\n");
for (auto& x : test.actual) {
fmt::print(" \"{}\"\n", escaped_string(x));
}
}
}
}
fmt::print("Total: passed {}/{} passable tests, {} auto-passed\n", passed, passable, auto_pass);
}
std::vector<std::string> get_test_pass_string(const std::string& name, int n_tests) {
return {fmt::format("Test \"{}\": {} Passes\n0\n", name, n_tests)};
}
void runtime_no_kernel() {
constexpr int argc = 4;
const char* argv[argc] = {"", "-fakeiso", "-debug", "-nokernel"};
@@ -121,4 +99,19 @@ void runtime_with_kernel() {
const char* argv[argc] = {"", "-fakeiso", "-debug"};
exec_runtime(argc, const_cast<char**>(argv));
}
void createDirIfAbsent(const std::string& path) {
if (!std::filesystem::is_directory(path) || !std::filesystem::exists(path)) {
std::filesystem::create_directory(path);
}
}
std::string getTemplateDir(const std::string& category) {
return file_util::get_file_path({"test/goalc/source_templates", category + "/"});
}
std::string getGeneratedDir(const std::string& category) {
return file_util::get_file_path({"test/goalc/source_generated", category + "/"});
}
std::string getFailedDir(const std::string& category) {
return file_util::get_file_path({"test/goalc/source_generated/failed", category + "/"});
}
} // namespace GoalTest
+16 -5
View File
@@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include "third-party/inja.hpp"
#include "goalc/compiler/Compiler.h"
#include "common\util\FileUtil.h"
@@ -22,18 +23,28 @@ struct CompilerTestRunner {
std::vector<Test> tests;
void run_test(const std::string& test_file,
void run_static_test(inja::Environment& env,
std::string& testCategory,
const std::string& test_file,
const std::vector<std::string>& expected,
MatchParam<int> truncate = {});
void run_test(const std::string& test_category,
const std::string& test_file,
const std::vector<std::string>& expected,
MatchParam<int> truncate = {});
void run_always_pass(const std::string& test_file);
void run_always_pass(const std::string& test_category, const std::string& test_file);
void print_summary();
};
std::vector<std::string> get_test_pass_string(const std::string& name, int n_tests);
void runtime_no_kernel();
void runtime_with_kernel();
void createDirIfAbsent(const std::string& path);
std::string getTemplateDir(const std::string& category);
std::string getGeneratedDir(const std::string& category);
std::string getFailedDir(const std::string& category);
} // namespace GoalTest
@@ -112,7 +112,7 @@ std::vector<IntegerParam> genIntegerTests(int numTests,
// In the interest of speed, we want to share the same thread/compiler across
// all the tests in this suite, so we have to over-ride this.
class IntegerTests : public testing::TestWithParam<IntegerParam> {
class ArithmeticTests : public testing::TestWithParam<IntegerParam> {
public:
// Per-test-suite set-up.
// Called before the first test in this test suite.
@@ -129,49 +129,104 @@ class IntegerTests : public testing::TestWithParam<IntegerParam> {
}
// You can define per-test set-up logic as usual.
virtual void SetUp() {}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
// You can define per-test tear-down logic as usual.
virtual void TearDown() {}
void TearDown() {}
// Common Resources Across all Tests in the Suite
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
// Just to promote better test organization, supports nesting the test files 1 directory deep
std::string testCategory = "arithmetic";
inja::Environment env{GoalTest::getTemplateDir(testCategory), GoalTest::getGeneratedDir(testCategory)};
};
// You must initialize the static variables outside of the declaration, or you'll run into unresolved external errors
std::thread IntegerTests::runtime_thread;
Compiler IntegerTests::compiler;
GoalTest::CompilerTestRunner IntegerTests::runner;
std::thread ArithmeticTests::runtime_thread;
Compiler ArithmeticTests::compiler;
GoalTest::CompilerTestRunner ArithmeticTests::runner;
// Finally, we define our generic test, given our custom class that represents our test inputs
// we can generate the lisp file, and pass along the path to the test runner
// If the test fails, the test runner will save the template file, with the expected/actual results into the `failed/` directory
TEST_P(IntegerTests, IntegerTests) {
// With separate input and output path
std::string templateDir = file_util::get_file_path({"test/goalc/source_templates/"});
std::string generatedDir = file_util::get_file_path({"test/goalc/source_generated/"});
inja::Environment env{templateDir, generatedDir};
TEST_P(ArithmeticTests, EvalIntegers) {
IntegerParam param = GetParam();
nlohmann::json data;
data["integer"] = param.toLisp();
std::string testFile = "integer-test-" + std::to_string(param.index) + ".generated.gc";
env.write("integer-test.template.gc", data, testFile);
runner.run_test(testFile, {param.eval()});
std::string testFile = "eval-integer-" + std::to_string(param.index) + ".generated.gc";
env.write("eval-integer.template.gc", data, testFile);
runner.run_test(testCategory, testFile, {param.eval()});
}
// ValuesIn, is not the only way to use a parameterized test, but the most applicable for this example
// You can actually get googletest to compute the permutations for you, which may be useful. Consult their docs.
INSTANTIATE_TEST_SUITE_P(InstantiationName,
IntegerTests,
// - https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#value-parameterized-tests
INSTANTIATE_TEST_SUITE_P(EvalIntegers,
ArithmeticTests,
testing::ValuesIn(genIntegerTests(4,
true,
true,
{IntegerParam(-2147483648),
IntegerParam(0), IntegerParam(-0)})));
TEST_F(ArithmeticTests, Addition) {
runner.run_static_test(env, testCategory, "add-int-literals.static.gc", {"13\n"});
runner.run_static_test(env, testCategory, "add-let.static.gc", {"7\n"});
}
TEST_F(ArithmeticTests, AddIntegerFunction) {
runner.run_static_test(env, testCategory, "add-function.static.gc", {"21\n"});
}
TEST_F(ArithmeticTests, AddIntegerMultiple) {
runner.run_static_test(env, testCategory, "add-int-multiple.static.gc", {"15\n"});
runner.run_static_test(env, testCategory, "add-int-multiple-2.static.gc", {"15\n"});
}
TEST_F(ArithmeticTests, AddIntegerVariables) {
runner.run_static_test(env, testCategory, "add-int-vars.static.gc", {"7\n"});
}
TEST_F(ArithmeticTests, AshFunction) {
runner.run_static_test(env, testCategory, "ash.static.gc", {"18\n"});
}
TEST_F(ArithmeticTests, Division) {
runner.run_static_test(env, testCategory, "divide-1.static.gc", {"6\n"});
runner.run_static_test(env, testCategory, "divide-2.static.gc", {"7\n"});
}
TEST_F(ArithmeticTests, IntegerSymbol) {
runner.run_static_test(env, testCategory, "negative-int-symbol.static.gc", {"-123\n"});
}
TEST_F(ArithmeticTests, Modulus) {
runner.run_static_test(env, testCategory, "mod.static.gc", {"7\n"});
}
TEST_F(ArithmeticTests, Multiplication) {
runner.run_static_test(env, testCategory, "multiply.static.gc", {"-12\n"});
runner.run_static_test(env, testCategory, "multiply-let.static.gc", {"3\n"});
}
TEST_F(ArithmeticTests, NestedFunctionCall) {
runner.run_static_test(env, testCategory, "nested-function.static.gc", {"10\n"});
}
TEST_F(ArithmeticTests, ShiftOperations) {
runner.run_static_test(env, testCategory, "shiftvs.static.gc", {"11\n"});
}
TEST_F(ArithmeticTests, Subtraction) {
runner.run_static_test(env, testCategory, "subtract-1.static.gc", {"4\n"});
runner.run_static_test(env, testCategory, "subtract-2.static.gc", {"4\n"});
runner.run_static_test(env, testCategory, "subtract-let.static.gc", {"3\n"});
}
+77
View File
@@ -0,0 +1,77 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct CollectionParam {
// TODO - Not Needed Yet
};
class CollectionTests : public testing::TestWithParam<CollectionParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "collections";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread CollectionTests::runtime_thread;
Compiler CollectionTests::compiler;
GoalTest::CompilerTestRunner CollectionTests::runner;
TEST_F(CollectionTests, Pairs) {
runner.run_static_test(env, testCategory, "empty-pair.static.gc", {"()\n0\n"});
runner.run_static_test(env, testCategory, "pair-check.static.gc", {"#t#f\n0\n"});
}
TEST_F(CollectionTests, Lists) {
runner.run_static_test(env, testCategory, "list.static.gc", {"(a b c d)\n0\n"});
}
TEST_F(CollectionTests, InlineArray) {
runner.run_static_test(env, testCategory, "inline-array-field.static.gc", {"16\n"});
}
TEST_F(CollectionTests, Operations) {
runner.run_static_test(env, testCategory, "cons.static.gc", {"(a . b)\n0\n"});
runner.run_static_test(env, testCategory, "car-cdr-get.static.gc", {"ab\n0\n"});
runner.run_static_test(env, testCategory, "car-cdr-set.static.gc", {"(c . d)\n0\n"});
runner.run_static_test(env, testCategory, "nested-car-cdr-set.static.gc", {"efgh\n((e . g) f . h)\n0\n"});
}
+80
View File
@@ -0,0 +1,80 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct ControlStatementParam {
// TODO - Not Needed Yet
};
class ControlStatementTests : public testing::TestWithParam<ControlStatementParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "control-statements";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread ControlStatementTests::runtime_thread;
Compiler ControlStatementTests::compiler;
GoalTest::CompilerTestRunner ControlStatementTests::runner;
TEST_F(ControlStatementTests, ConditionalCompilation) {
runner.run_static_test(env, testCategory, "conditional-compilation.static.gc", {"3\n"});
// TODO - test-conditional-compilation-2.gc
// these numbers match the game's memory layout for where the symbol table lives.
// it's probably not 100% needed to get this exactly, but it's a good sign that the global
// heap lives in the right spot because there should be no divergence in memory layout when its
// built. This also checks that #t, #f get "hashed" to the correct spot.
}
TEST_F(ControlStatementTests, Blocks) {
runner.run_static_test(env, testCategory, "nested-blocks-1.static.gc", {"7\n"});
runner.run_static_test(env, testCategory, "nested-blocks-2.static.gc", {"8\n"});
runner.run_static_test(env, testCategory, "nested-blocks-3.static.gc", {"7\n"});
}
TEST_F(ControlStatementTests, GoTo) {
runner.run_static_test(env, testCategory, "goto.static.gc", {"3\n"});
}
TEST_F(ControlStatementTests, Branch) {
runner.run_static_test(env, testCategory, "return-value-of-if.static.gc", {"123\n"});
}
+76
View File
@@ -0,0 +1,76 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct FloatParam {
// TODO - Not Needed Yet
};
class FloatTests : public testing::TestWithParam<FloatParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "float";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread FloatTests::runtime_thread;
Compiler FloatTests::compiler;
GoalTest::CompilerTestRunner FloatTests::runner;
TEST_F(FloatTests, Constants) {
runner.run_static_test(env, testCategory, "float.static.gc", {"1067316150\n"});
runner.run_static_test(env, testCategory, "function-return-float-constant.static.gc", {"3.14149\n0\n"});
}
TEST_F(FloatTests, Operations) {
runner.run_static_test(env, testCategory, "float-pow.static.gc", {"256\n0\n"});
runner.run_static_test(env, testCategory, "float-product.static.gc", {"120.0000\n0\n"});
}
TEST_F(FloatTests, Symbols) {
runner.run_static_test(env, testCategory, "float-in-symbol.static.gc", {"2345.6000\n0\n"});
}
TEST_F(FloatTests, Functions) {
runner.run_static_test(env, testCategory, "float-function.static.gc", {"10.152\n0\n"});
runner.run_static_test(env, testCategory, "nested-float-functions.static.gc", {"i 1.4400 3.4000\nr 10.1523\ni 1.2000 10.1523\nr 17.5432\n17.543 10.152\n0\n"});
}
+79
View File
@@ -0,0 +1,79 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct FunctionParam {
// TODO - Not Needed Yet
};
class FunctionTests : public testing::TestWithParam<FunctionParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "functions";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread FunctionTests::runtime_thread;
Compiler FunctionTests::compiler;
GoalTest::CompilerTestRunner FunctionTests::runner;
TEST_F(FunctionTests, Definitions) {
runner.run_static_test(env, testCategory, "defun-return-constant.static.gc", {"12\n"});
runner.run_static_test(env, testCategory, "defun-return-symbol.static.gc", {"42\n"});
}
TEST_F(FunctionTests, ReturnValue) {
runner.run_static_test(env, testCategory, "return.static.gc", {"77\n"});
runner.run_static_test(env, testCategory, "return-arg.static.gc", {"23\n"});
runner.run_static_test(env, testCategory, "return-colors.static.gc", {"77\n"});
}
TEST_F(FunctionTests, Calling) {
runner.run_static_test(env, testCategory, "nested-call.static.gc", {"2\n"});
runner.run_static_test(env, testCategory, "inline-call.static.gc", {"44\n"});
runner.run_static_test(env, testCategory, "simple-call.static.gc", {"30\n"});
}
TEST_F(FunctionTests, Anonymous) {
runner.run_static_test(env, testCategory, "declare-inline.static.gc", {"32\n"});
runner.run_static_test(env, testCategory, "lambda-1.static.gc", {"2\n"});
}
+70
View File
@@ -0,0 +1,70 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct LibraryParam {
// TODO - Not Needed Yet
};
class LibraryTests : public testing::TestWithParam<LibraryParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "library";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread LibraryTests::runtime_thread;
Compiler LibraryTests::compiler;
GoalTest::CompilerTestRunner LibraryTests::runner;
TEST_F(LibraryTests, Set) {
runner.run_static_test(env, testCategory, "set-symbol.static.gc", {"22\n"});
}
TEST_F(LibraryTests, Protect) {
runner.run_static_test(env, testCategory, "protect.static.gc", {"33\n"});
}
TEST_F(LibraryTests, Align) {
runner.run_static_test(env, testCategory, "align16-1.static.gc", {"80\n"});
runner.run_static_test(env, testCategory, "align16-2.static.gc", {"64\n"});
}
+68
View File
@@ -0,0 +1,68 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct LogicParam {
// TODO - Not Needed Yet
};
class LogicTests : public testing::TestWithParam<LogicParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "logic";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread LogicTests::runtime_thread;
Compiler LogicTests::compiler;
GoalTest::CompilerTestRunner LogicTests::runner;
TEST_F(LogicTests, LogicalOperators) {
runner.run_static_test(env, testCategory, "logand.static.gc", {"4\n"});
runner.run_static_test(env, testCategory, "logior.static.gc", {"60\n"});
runner.run_static_test(env, testCategory, "logxor.static.gc", {"56\n"});
}
TEST_F(LogicTests, Comparison) {
runner.run_static_test(env, testCategory, "signed-int-compare.static.gc", {"12\n"});
}
+66
View File
@@ -0,0 +1,66 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct LoopRecurParam {
// TODO - Not Needed Yet
};
class LoopRecurTests : public testing::TestWithParam<LoopRecurParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "loop_recur";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread LoopRecurTests::runtime_thread;
Compiler LoopRecurTests::compiler;
GoalTest::CompilerTestRunner LoopRecurTests::runner;
TEST_F(LoopRecurTests, DoTimes) {
runner.run_static_test(env, testCategory, "dotimes.static.gc", {"4950\n"});
}
TEST_F(LoopRecurTests, Factorial) {
runner.run_static_test(env, testCategory, "factorial-recursive.static.gc", {"3628800\n"});
runner.run_static_test(env, testCategory, "factorial-iterative.static.gc", {"3628800\n"});
}
+65
View File
@@ -0,0 +1,65 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct MacroParam {
// TODO - Not Needed Yet
};
class MacroTests : public testing::TestWithParam<MacroParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "macros";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread MacroTests::runtime_thread;
Compiler MacroTests::compiler;
GoalTest::CompilerTestRunner MacroTests::runner;
TEST_F(MacroTests, Defsmacro) {
runner.run_static_test(env, testCategory, "defsmacro-defgmacro.static.gc", {"20\n"});
}
TEST_F(MacroTests, Desfun) {
runner.run_static_test(env, testCategory, "desfun.static.gc", {"4\n"});
}
+61
View File
@@ -0,0 +1,61 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct MethodParam {
// TODO - Not Needed Yet
};
class MethodTests : public testing::TestWithParam<MethodParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "methods";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread MethodTests::runtime_thread;
Compiler MethodTests::compiler;
GoalTest::CompilerTestRunner MethodTests::runner;
TEST_F(MethodTests, DeReference) {
runner.run_static_test(env, testCategory, "methods.static.gc", {"#t#t\n0\n"});
}
+65
View File
@@ -0,0 +1,65 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct PointerParam {
// TODO - Not Needed Yet
};
class PointerTests : public testing::TestWithParam<PointerParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "pointers";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread PointerTests::runtime_thread;
Compiler PointerTests::compiler;
GoalTest::CompilerTestRunner PointerTests::runner;
TEST_F(PointerTests, DeReference) {
runner.run_static_test(env, testCategory, "deref-simple.static.gc", {"structure\n0\n"});
}
TEST_F(PointerTests, Pointers) {
runner.run_static_test(env, testCategory, "pointers.static.gc", {"13\n"});
}
+88
View File
@@ -0,0 +1,88 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct StringParam {
// TODO - Not Needed Yet
};
class StringTests : public testing::TestWithParam<StringParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "strings";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread StringTests::runtime_thread;
Compiler StringTests::compiler;
GoalTest::CompilerTestRunner StringTests::runner;
TEST_F(StringTests, Constants) {
std::string expected = "\"test string!\"";
runner.run_static_test(env, testCategory, "string-constant-1.static.gc", {expected}, expected.size());
// TODO - runner.run_static_test(env, testCategory, "string-constant-2.static.gc", {});
}
TEST_F(StringTests, Symbols) {
runner.run_static_test(env, testCategory, "quote-symbol.static.gc", {"banana\n0\n"});
std::string expected = "test-string";
runner.run_static_test(env, testCategory, "string-symbol.static.gc", {expected}, expected.size());
}
TEST_F(StringTests, Formatting) {
runner.run_static_test(env, testCategory, "format-reg-order.static.gc", {"test 1 2 3 4 5 6\n0\n"});
}
// expected =
// "test newline\nnewline\ntest tilde ~ \ntest A print boxed-string: \"boxed string!\"\ntest
// A " "print symbol: a-symbol\ntest A make boxed object longer: \"srt\"!\ntest A
// " "non-default pad: zzzzzzpad-me\ntest A shorten(4): a23~\ntest A don'tchange(4):
// a234\ntest A " "shorten with pad(4): sho~\ntest A a few things \"one thing\" a-second
// integer #<compiled " "function @ #x161544>\n";
//
// expected += "test S a string a-symbol another string!\n";
// expected += "test C ) ]\n";
// expected += "test P (no type) #<compiled function @ #x161544>\n";
// expected += "test P (with type) 1447236\n";
//
// // todo, finish format testing.
// runner.run_test("test-format.gc", {expected}, expected.size());
+64
View File
@@ -0,0 +1,64 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct SymbolParam {
// TODO - Not Needed Yet
};
class SymbolTests : public testing::TestWithParam<SymbolParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "symbols";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread SymbolTests::runtime_thread;
Compiler SymbolTests::compiler;
GoalTest::CompilerTestRunner SymbolTests::runner;
TEST_F(SymbolTests, GetSymbol) {
runner.run_static_test(env, testCategory, "get-symbol-1.static.gc",
{"1342756\n"}); // 0x147d24 in hex
runner.run_static_test(env, testCategory, "get-symbol-2.static.gc",
{"1342764\n"}); // 0x147d2c in hex
}
+72
View File
@@ -0,0 +1,72 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct VariableParam {
// TODO - Not Needed Yet
};
class VariableTests : public testing::TestWithParam<VariableParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "variables";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread VariableTests::runtime_thread;
Compiler VariableTests::compiler;
GoalTest::CompilerTestRunner VariableTests::runner;
TEST_F(VariableTests, Globals) {
runner.run_static_test(env, testCategory, "defglobalconstant-1.static.gc", {"17\n"});
runner.run_static_test(env, testCategory, "defglobalconstant-2.static.gc", {"18\n"});
}
TEST_F(VariableTests, Definitions) {
runner.run_static_test(env, testCategory, "define.static.gc", {"17\n"});
}
TEST_F(VariableTests, Let) {
runner.run_static_test(env, testCategory, "let.static.gc", {"30\n"});
runner.run_static_test(env, testCategory, "let-star.static.gc", {"30\n"});
runner.run_static_test(env, testCategory, "mlet.static.gc", {"10\n"});
}
+116
View File
@@ -0,0 +1,116 @@
#include <thread>
#include <chrono>
#include "gtest/gtest.h"
#include "game/runtime.h"
#include "goalc/listener/Listener.h"
#include "goalc/compiler/Compiler.h"
#include "third-party/inja.hpp"
#include "third-party/json.hpp"
#include <common\util\FileUtil.h>
#include <test\goalc\framework\test_runner.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <sstream>
#include <iostream>
#include <random>
#include <filesystem>
struct WithGameParam {
// TODO - Not Needed Yet
};
class WithGameTests : public testing::TestWithParam<WithGameParam> {
public:
static void SetUpTestSuite() {
runtime_thread = std::thread((GoalTest::runtime_no_kernel));
runner.c = &compiler;
}
static void TearDownTestSuite() {
compiler.shutdown_target();
runtime_thread.join();
}
void SetUp() {
GoalTest::createDirIfAbsent(GoalTest::getTemplateDir(testCategory));
GoalTest::createDirIfAbsent(GoalTest::getGeneratedDir(testCategory));
}
void TearDown() {}
static std::thread runtime_thread;
static Compiler compiler;
static GoalTest::CompilerTestRunner runner;
std::string testCategory = "with_game";
inja::Environment env{GoalTest::getTemplateDir(testCategory),
GoalTest::getGeneratedDir(testCategory)};
};
std::thread WithGameTests::runtime_thread;
Compiler WithGameTests::compiler;
GoalTest::CompilerTestRunner WithGameTests::runner;
// TODO - havn't done anything with these really yet
TEST_F(WithGameTests, All) {
runner.run_static_test(env, testCategory, "defun-return-constant.static.gc", {"12\n"});
runner.run_static_test(env, testCategory, "defun-return-symbol.static.gc", {"42\n"});
runner.run_static_test(env, testCategory, "test-min-max.gc", {"10\n"});
runner.run_static_test(env, testCategory, "test-bfloat.gc",
{"data 1.2330 print 1.2330 type bfloat\n0\n"});
runner.run_static_test(env, testCategory, "test-basic-type-check.gc", {"#f#t#t#f#t#f#t#t\n0\n"});
runner.run_static_test(env, testCategory, "test-condition-boolean.gc", {"4\n"});
runner.run_static_test(env, testCategory, "test-type-type.gc", {"#t#f\n0\n"});
runner.run_static_test(env, testCategory, "test-access-inline-array.gc", {"1.2345\n0\n"});
runner.run_static_test(env, testCategory, "test-find-parent-method.gc", {"\"test pass!\"\n0\n"});
runner.run_static_test(env, testCategory, "test-ref.gc", {"83\n"});
runner.run_static_test(env, testCategory, "test-pair-asize.gc", {"8\n"});
runner.run_static_test(env, testCategory, "test-last.gc", {"d\n0\n"});
runner.run_static_test(
env, testCategory, "test-sort.gc",
{"(24 16 32 56 72 1234 -34 25 654)\n(1234 654 72 56 32 25 24 16 -34)\n0\n"});
runner.run_static_test(
env, testCategory, "test-sort-2.gc",
{"(24 16 32 56 72 1234 -34 25 654)\n(-34 16 24 25 32 56 72 654 1234)\n0\n"});
runner.run_static_test(
env, testCategory, "test-sort-3.gc",
{"(24 16 32 56 72 1234 -34 25 654)\n(-34 16 24 25 32 56 72 654 1234)\n0\n"});
runner.run_static_test(env, testCategory, "test-pair-length.gc", {"6\n"});
runner.run_static_test(env, testCategory, "test-member-1.gc", {"(c d)\n0\n"});
runner.run_static_test(env, testCategory, "test-member-2.gc", {"#f\n0\n"});
runner.run_static_test(env, testCategory, "test-assoc-1.gc", {"w\n0\n"});
runner.run_static_test(env, testCategory, "test-assoc-2.gc", {"#f\n0\n"});
runner.run_static_test(env, testCategory, "test-assoce-1.gc", {"x\n0\n"});
runner.run_static_test(env, testCategory, "test-assoce-2.gc", {"x\n0\n"});
runner.run_static_test(env, testCategory, "test-append.gc", {"(a b c d e)\n0\n"});
runner.run_static_test(env, testCategory, "test-delete-list.gc", {"(a b d e)\n0\n"});
runner.run_static_test(env, testCategory, "test-delete-car.gc", {"((a . b) (e . f))\n#f\n0\n"});
runner.run_static_test(env, testCategory, "test-insert-cons.gc",
{"((c . w) (a . b) (e . f))\n0\n"});
runner.run_static_test(env, testCategory, "test-new-inline-array-class.gc", {"2820\n"});
runner.run_static_test(env, testCategory, "test-memcpy.gc", {"13\n"});
runner.run_static_test(env, testCategory, "test-memset.gc", {"11\n"});
runner.run_static_test(env, testCategory, "test-binteger-print.gc", {"-17\n0\n"});
runner.run_static_test(env, testCategory, "test-tests.gc",
{"Test Failed On Test 0: \"unknown\"\nTest Failed On Test 0: "
"\"test\"\nTest \"test-of-test\": 1 Passes\n0\n"});
runner.run_static_test(env, testCategory, "test-type-arrays.gc",
{"Test \"test-type-arrays\": 3 Passes\n0\n"});
runner.run_static_test(env, testCategory, "test-number-comparison.gc",
{"Test \"number-comparison\": 14 Passes\n0\n"});
/*runner.run_static_test(env, testCategory, "test-approx-pi.gc",
get_test_pass_string("approx-pi", 4));
runner.run_static_test(env, testCategory, "test-dynamic-type.gc",
get_test_pass_string("dynamic-type", 4));
runner.run_static_test(env, testCategory, "test-string-type.gc",
get_test_pass_string("string-type", 4));
runner.run_static_test(env, testCategory, "test-new-string.gc",
get_test_pass_string("new-string", 5));*/
//runner.run_static_test(env, testCategory, "test-addr-of.gc", get_test_pass_string("addr-of", 2));
runner.run_static_test(env, testCategory, "test-set-self.gc", {"#t\n0\n"});
}
-301
View File
@@ -10,178 +10,6 @@ TEST(CompilerAndRuntime, ConstructCompiler) {
Compiler compiler;
}
namespace {
std::string escaped_string(const std::string& in) {
std::string result;
for (auto x : in) {
switch (x) {
case '\n':
result.append("\\n");
break;
case '\t':
result.append("\\t");
break;
default:
result.push_back(x);
}
}
return result;
}
struct CompilerTestRunner {
Compiler* c = nullptr;
struct Test {
std::vector<std::string> expected, actual;
std::string test_name;
bool auto_pass = false;
};
std::vector<Test> tests;
void run_test(const std::string& test_file,
const std::vector<std::string>& expected,
MatchParam<int> truncate = {}) {
fprintf(stderr, "Testing %s\n", test_file.c_str());
auto result = c->run_test("goal_src/test/" + test_file);
if (!truncate.is_wildcard) {
for (auto& x : result) {
x = x.substr(0, truncate.value);
}
}
EXPECT_EQ(result, expected);
tests.push_back({expected, result, test_file, false});
}
void run_always_pass(const std::string& test_file) {
c->run_test("goal_src/test/" + test_file);
tests.push_back({{}, {}, test_file, true});
}
void print_summary() {
fmt::print("~~ Compiler Test Summary for {} tests... ~~\n", tests.size());
int passed = 0;
int passable = 0;
int auto_pass = 0;
for (auto& test : tests) {
if (test.auto_pass) {
auto_pass++;
fmt::print("[{:40}] AUTO-PASS!\n", test.test_name);
} else {
passable++;
if (test.expected == test.actual) {
fmt::print("[{:40}] PASS!\n", test.test_name);
passed++;
} else {
fmt::print("[{:40}] FAIL!\n", test.test_name);
fmt::print("expected:\n");
for (auto& x : test.expected) {
fmt::print(" \"{}\"\n", escaped_string(x));
}
fmt::print("result:\n");
for (auto& x : test.actual) {
fmt::print(" \"{}\"\n", escaped_string(x));
}
}
}
}
fmt::print("Total: passed {}/{} passable tests, {} auto-passed\n", passed, passable, auto_pass);
}
};
std::vector<std::string> get_test_pass_string(const std::string& name, int n_tests) {
return {fmt::format("Test \"{}\": {} Passes\n0\n", name, n_tests)};
}
void runtime_no_kernel() {
constexpr int argc = 4;
const char* argv[argc] = {"", "-fakeiso", "-debug", "-nokernel"};
exec_runtime(argc, const_cast<char**>(argv));
}
void runtime_with_kernel() {
constexpr int argc = 3;
const char* argv[argc] = {"", "-fakeiso", "-debug"};
exec_runtime(argc, const_cast<char**>(argv));
}
} // namespace
TEST(CompilerAndRuntime, StartRuntime) {
std::thread runtime_thread(runtime_no_kernel);
listener::Listener listener;
while (!listener.is_connected()) {
listener.connect_to_target();
std::this_thread::sleep_for(std::chrono::microseconds(1000));
}
listener.send_reset(true);
runtime_thread.join();
}
TEST(CompilerAndRuntime, BuildGameAndTest) {
Compiler compiler;
try {
compiler.run_test_no_load("goal_src/test/test-build-game.gc");
} catch (std::exception& e) {
fprintf(stderr, "caught exception %s\n", e.what());
EXPECT_TRUE(false);
}
// todo, tests after loading the game.
CompilerTestRunner runner;
runner.c = &compiler;
std::thread runtime_thread(runtime_with_kernel);
runner.run_test("test-min-max.gc", {"10\n"});
runner.run_test("test-bfloat.gc", {"data 1.2330 print 1.2330 type bfloat\n0\n"});
runner.run_test("test-basic-type-check.gc", {"#f#t#t#f#t#f#t#t\n0\n"});
runner.run_test("test-condition-boolean.gc", {"4\n"});
runner.run_test("test-type-type.gc", {"#t#f\n0\n"});
runner.run_test("test-access-inline-array.gc", {"1.2345\n0\n"});
runner.run_test("test-find-parent-method.gc", {"\"test pass!\"\n0\n"});
runner.run_test("test-ref.gc", {"83\n"});
runner.run_test("test-pair-asize.gc", {"8\n"});
runner.run_test("test-last.gc", {"d\n0\n"});
runner.run_test("test-sort.gc",
{"(24 16 32 56 72 1234 -34 25 654)\n(1234 654 72 56 32 25 24 16 -34)\n0\n"});
runner.run_test("test-sort-2.gc",
{"(24 16 32 56 72 1234 -34 25 654)\n(-34 16 24 25 32 56 72 654 1234)\n0\n"});
runner.run_test("test-sort-3.gc",
{"(24 16 32 56 72 1234 -34 25 654)\n(-34 16 24 25 32 56 72 654 1234)\n0\n"});
runner.run_test("test-pair-length.gc", {"6\n"});
runner.run_test("test-member-1.gc", {"(c d)\n0\n"});
runner.run_test("test-member-2.gc", {"#f\n0\n"});
runner.run_test("test-assoc-1.gc", {"w\n0\n"});
runner.run_test("test-assoc-2.gc", {"#f\n0\n"});
runner.run_test("test-assoce-1.gc", {"x\n0\n"});
runner.run_test("test-assoce-2.gc", {"x\n0\n"});
runner.run_test("test-append.gc", {"(a b c d e)\n0\n"});
runner.run_test("test-delete-list.gc", {"(a b d e)\n0\n"});
runner.run_test("test-delete-car.gc", {"((a . b) (e . f))\n#f\n0\n"});
runner.run_test("test-insert-cons.gc", {"((c . w) (a . b) (e . f))\n0\n"});
runner.run_test("test-new-inline-array-class.gc", {"2820\n"});
runner.run_test("test-memcpy.gc", {"13\n"});
runner.run_test("test-memset.gc", {"11\n"});
runner.run_test("test-binteger-print.gc", {"-17\n0\n"});
runner.run_test("test-tests.gc", {"Test Failed On Test 0: \"unknown\"\nTest Failed On Test 0: "
"\"test\"\nTest \"test-of-test\": 1 Passes\n0\n"});
runner.run_test("test-type-arrays.gc", {"Test \"test-type-arrays\": 3 Passes\n0\n"});
runner.run_test("test-number-comparison.gc", {"Test \"number-comparison\": 14 Passes\n0\n"});
runner.run_test("test-approx-pi.gc", get_test_pass_string("approx-pi", 4));
runner.run_test("test-dynamic-type.gc", get_test_pass_string("dynamic-type", 4));
runner.run_test("test-string-type.gc", get_test_pass_string("string-type", 4));
runner.run_test("test-new-string.gc", get_test_pass_string("new-string", 5));
runner.run_test("test-addr-of.gc", get_test_pass_string("addr-of", 2));
runner.run_test("test-set-self.gc", {"#t\n0\n"});
runner.print_summary();
compiler.shutdown_target();
runtime_thread.join();
}
// TODO -move these into another file?
TEST(CompilerAndRuntime, InlineIsInline) {
Compiler compiler;
@@ -224,132 +52,3 @@ TEST(CompilerAndRuntime, AllowInline) {
EXPECT_EQ(got_call, 1);
}
TEST(CompilerAndRuntime, CompilerTests) {
std::thread runtime_thread(runtime_no_kernel);
Compiler compiler;
CompilerTestRunner runner;
runner.c = &compiler;
runner.run_test("test-return-integer-1.gc", {"4886718345\n"});
runner.run_test("test-return-integer-2.gc", {"23\n"});
runner.run_test("test-return-integer-3.gc", {"-17\n"});
runner.run_test("test-return-integer-4.gc", {"-2147483648\n"});
runner.run_test("test-return-integer-5.gc", {"-2147483649\n"});
runner.run_test("test-return-integer-6.gc", {"0\n"});
runner.run_test("test-return-integer-7.gc", {"-123\n"});
runner.run_test("test-conditional-compilation-1.gc", {"3\n"});
// todo, test-conditional-compilation-2.gc
// these numbers match the game's memory layout for where the symbol table lives.
// it's probably not 100% needed to get this exactly, but it's a good sign that the global
// heap lives in the right spot because there should be no divergence in memory layout when its
// built. This also checks that #t, #f get "hashed" to the correct spot.
runner.run_test("test-get-symbol-1.gc", {"1342756\n"}); // 0x147d24 in hex
runner.run_test("test-get-symbol-2.gc", {"1342764\n"}); // 0x147d2c in hex
runner.run_test("test-define-1.gc", {"17\n"});
runner.run_test("test-nested-blocks-1.gc", {"7\n"});
runner.run_test("test-nested-blocks-2.gc", {"8\n"});
runner.run_test("test-nested-blocks-3.gc", {"7\n"});
runner.run_test("test-goto-1.gc", {"3\n"});
runner.run_test("test-defglobalconstant-1.gc", {"17\n"});
runner.run_test("test-defglobalconstant-2.gc", {"18\n"});
runner.run_test("test-simple-function-call.gc", {"30\n"});
runner.run_test("test-application-lambda-1.gc", {"2\n"});
runner.run_test("test-let-1.gc", {"30\n"});
runner.run_test("test-let-star-1.gc", {"30\n"});
runner.run_always_pass("test-string-constant-1.gc");
std::string expected = "\"test string!\"";
runner.run_test("test-string-constant-2.gc", {expected}, expected.size());
runner.run_test("test-defun-return-constant.gc", {"12\n"});
runner.run_test("test-defun-return-symbol.gc", {"42\n"});
runner.run_test("test-function-return-arg.gc", {"23\n"});
runner.run_test("test-nested-function-call.gc", {"2\n"});
// math
runner.run_test("test-add-int-constants.gc", {"13\n"});
runner.run_test("test-add-int-vars.gc", {"7\n"});
runner.run_test("test-add-int-multiple.gc", {"15\n"});
runner.run_test("test-add-int-multiple-2.gc", {"15\n"});
runner.run_test("test-add-function-returns.gc", {"21\n"});
runner.run_test("test-sub-1.gc", {"4\n"});
runner.run_test("test-sub-2.gc", {"4\n"});
runner.run_test("test-mul-1.gc", {"-12\n"});
runner.run_test("test-three-reg-add.gc", {"7\n"});
runner.run_test("test-three-reg-sub.gc", {"3\n"});
runner.run_test("test-three-reg-mult.gc", {"3\n"});
runner.run_test("test-div-1.gc", {"6\n"});
runner.run_test("test-div-2.gc", {"7\n"});
runner.run_test("test-shiftvs.gc", {"11\n"});
runner.run_test("test-ash.gc", {"18\n"});
runner.run_test("test-negative-integer-symbol.gc", {"-123\n"});
runner.run_test("test-mod.gc", {"7\n"});
runner.run_test("test-nested-function-call-2.gc", {"10\n"});
runner.run_test("test-logand.gc", {"4\n"});
runner.run_test("test-logior.gc", {"60\n"});
runner.run_test("test-logxor.gc", {"56\n"});
expected = "test-string";
runner.run_test("test-string-symbol.gc", {expected}, expected.size());
runner.run_test("test-declare-inline.gc", {"32\n"});
runner.run_test("test-inline-call.gc", {"44\n"});
// float
runner.run_test("test-floating-point-1.gc", {"1067316150\n"});
runner.run_test("test-mlet.gc", {"10\n"});
runner.run_test("test-set-symbol.gc", {"22\n"});
runner.run_test("test-defsmacro-defgmacro.gc", {"20\n"});
runner.run_test("test-desfun.gc", {"4\n"});
runner.run_test("test-factorial-recursive.gc", {"3628800\n"});
runner.run_test("test-factorial-loop.gc", {"3628800\n"});
runner.run_test("test-protect.gc", {"33\n"});
runner.run_test("test-format-reg-order.gc", {"test 1 2 3 4 5 6\n0\n"});
runner.run_test("test-quote-symbol.gc", {"banana\n0\n"});
// expected =
// "test newline\nnewline\ntest tilde ~ \ntest A print boxed-string: \"boxed string!\"\ntest
// A " "print symbol: a-symbol\ntest A make boxed object longer: \"srt\"!\ntest A
// " "non-default pad: zzzzzzpad-me\ntest A shorten(4): a23~\ntest A don'tchange(4):
// a234\ntest A " "shorten with pad(4): sho~\ntest A a few things \"one thing\" a-second
// integer #<compiled " "function @ #x161544>\n";
//
// expected += "test S a string a-symbol another string!\n";
// expected += "test C ) ]\n";
// expected += "test P (no type) #<compiled function @ #x161544>\n";
// expected += "test P (with type) 1447236\n";
//
// // todo, finish format testing.
// runner.run_test("test-format.gc", {expected}, expected.size());
runner.run_test("test-float-product.gc", {"120.0000\n0\n"});
runner.run_test("test-float-in-symbol.gc", {"2345.6000\n0\n"});
runner.run_test("test-function-return-constant-float.gc", {"3.14149\n0\n"});
runner.run_test("test-float-function.gc", {"10.152\n0\n"});
runner.run_test("test-float-pow-function.gc", {"256\n0\n"});
runner.run_test("test-nested-float-functions.gc",
{"i 1.4400 3.4000\nr 10.1523\ni 1.2000 10.1523\nr 17.5432\n17.543 10.152\n0\n"});
runner.run_test("test-deref-simple.gc", {"structure\n0\n"});
runner.run_test("test-align16-1.gc", {"80\n"});
runner.run_test("test-align16-2.gc", {"64\n"});
runner.run_test("test-return-from-f.gc", {"77\n"});
runner.run_test("test-return-from-f-tricky-color.gc", {"77\n"});
runner.run_test("test-signed-int-compare.gc", {"12\n"});
runner.run_test("test-return-value-of-if.gc", {"123\n"});
runner.run_test("test-inline-array-field.gc", {"16\n"});
runner.run_test("test-empty-pair.gc", {"()\n0\n"});
runner.run_test("test-pair-check.gc", {"#t#f\n0\n"});
runner.run_test("test-cons.gc", {"(a . b)\n0\n"});
runner.run_test("test-list.gc", {"(a b c d)\n0\n"});
runner.run_test("test-car-cdr-get.gc", {"ab\n0\n"});
runner.run_test("test-car-cdr-set.gc", {"(c . d)\n0\n"});
runner.run_test("test-nested-car-cdr-set.gc", {"efgh\n((e . g) f . h)\n0\n"});
runner.run_test("test-dotimes.gc", {"4950\n"});
runner.run_test("test-methods.gc", {"#t#t\n0\n"});
runner.run_test("test-pointers-1.gc", {"13\n"});
compiler.shutdown_target();
runtime_thread.join();
runner.print_summary();
}