From df6e6dd2a28ecea7868e1474455e6409fcab5c88 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Thu, 8 Oct 2020 00:06:48 -0400 Subject: [PATCH] Create new categorized test classes, for the most part just a copy of current tests into new framework --- test/CMakeLists.txt | 34 +- test/goalc/CMakeLists.txt | 24 ++ test/goalc/README.md | 16 +- test/goalc/framework/test_runner.cpp | 83 +++-- test/goalc/framework/test_runner.h | 21 +- ...mpiler_integer.cpp => test_arithmetic.cpp} | 93 ++++-- test/goalc/test_collections.cpp | 77 +++++ test/goalc/test_control_statements.cpp | 80 +++++ test/goalc/test_float.cpp | 76 +++++ test/goalc/test_functions.cpp | 79 +++++ test/goalc/test_library.cpp | 70 ++++ test/goalc/test_logic.cpp | 68 ++++ test/goalc/test_loop_recur.cpp | 66 ++++ test/goalc/test_macros.cpp | 65 ++++ test/goalc/test_methods.cpp | 61 ++++ test/goalc/test_pointers.cpp | 65 ++++ test/goalc/test_strings.cpp | 88 +++++ test/goalc/test_symbols.cpp | 64 ++++ test/goalc/test_variables.cpp | 72 +++++ test/goalc/test_with_game.cpp | 116 +++++++ test/test_compiler_and_runtime.cpp | 301 ------------------ 21 files changed, 1222 insertions(+), 397 deletions(-) create mode 100644 test/goalc/CMakeLists.txt rename test/goalc/{test_compiler_integer.cpp => test_arithmetic.cpp} (66%) create mode 100644 test/goalc/test_collections.cpp create mode 100644 test/goalc/test_control_statements.cpp create mode 100644 test/goalc/test_float.cpp create mode 100644 test/goalc/test_functions.cpp create mode 100644 test/goalc/test_library.cpp create mode 100644 test/goalc/test_logic.cpp create mode 100644 test/goalc/test_loop_recur.cpp create mode 100644 test/goalc/test_macros.cpp create mode 100644 test/goalc/test_methods.cpp create mode 100644 test/goalc/test_pointers.cpp create mode 100644 test/goalc/test_strings.cpp create mode 100644 test/goalc/test_symbols.cpp create mode 100644 test/goalc/test_variables.cpp create mode 100644 test/goalc/test_with_game.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 983b8fc00e..37d553f4ca 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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() diff --git a/test/goalc/CMakeLists.txt b/test/goalc/CMakeLists.txt new file mode 100644 index 0000000000..dbdacdd5db --- /dev/null +++ b/test/goalc/CMakeLists.txt @@ -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" +) diff --git a/test/goalc/README.md b/test/goalc/README.md index 530de3809d..714911578a 100644 --- a/test/goalc/README.md +++ b/test/goalc/README.md @@ -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? \ No newline at end of file diff --git a/test/goalc/framework/test_runner.cpp b/test/goalc/framework/test_runner.cpp index d090a0271b..5380394881 100644 --- a/test/goalc/framework/test_runner.cpp +++ b/test/goalc/framework/test_runner.cpp @@ -12,6 +12,7 @@ #include "goalc/compiler/Compiler.h" #include "common\util\FileUtil.h" +#include 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& expected, + MatchParam 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& expected, MatchParam 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 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(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 diff --git a/test/goalc/framework/test_runner.h b/test/goalc/framework/test_runner.h index ea9489570d..504134889f 100644 --- a/test/goalc/framework/test_runner.h +++ b/test/goalc/framework/test_runner.h @@ -3,6 +3,7 @@ #include #include +#include "third-party/inja.hpp" #include "goalc/compiler/Compiler.h" #include "common\util\FileUtil.h" @@ -22,18 +23,28 @@ struct CompilerTestRunner { std::vector 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& expected, + MatchParam truncate = {}); + + void run_test(const std::string& test_category, + const std::string& test_file, const std::vector& expected, MatchParam 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 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 diff --git a/test/goalc/test_compiler_integer.cpp b/test/goalc/test_arithmetic.cpp similarity index 66% rename from test/goalc/test_compiler_integer.cpp rename to test/goalc/test_arithmetic.cpp index a17c8097e5..1d40d5d24f 100644 --- a/test/goalc/test_compiler_integer.cpp +++ b/test/goalc/test_arithmetic.cpp @@ -112,7 +112,7 @@ std::vector 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 { +class ArithmeticTests : public testing::TestWithParam { public: // Per-test-suite set-up. // Called before the first test in this test suite. @@ -129,49 +129,104 @@ class IntegerTests : public testing::TestWithParam { } // 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"}); +} diff --git a/test/goalc/test_collections.cpp b/test/goalc/test_collections.cpp new file mode 100644 index 0000000000..ecf54cb731 --- /dev/null +++ b/test/goalc/test_collections.cpp @@ -0,0 +1,77 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct CollectionParam { + // TODO - Not Needed Yet +}; + +class CollectionTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_control_statements.cpp b/test/goalc/test_control_statements.cpp new file mode 100644 index 0000000000..46a502ba5c --- /dev/null +++ b/test/goalc/test_control_statements.cpp @@ -0,0 +1,80 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct ControlStatementParam { + // TODO - Not Needed Yet +}; + +class ControlStatementTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_float.cpp b/test/goalc/test_float.cpp new file mode 100644 index 0000000000..000a6e3fff --- /dev/null +++ b/test/goalc/test_float.cpp @@ -0,0 +1,76 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct FloatParam { + // TODO - Not Needed Yet +}; + +class FloatTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_functions.cpp b/test/goalc/test_functions.cpp new file mode 100644 index 0000000000..83b20b8ad3 --- /dev/null +++ b/test/goalc/test_functions.cpp @@ -0,0 +1,79 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct FunctionParam { + // TODO - Not Needed Yet +}; + +class FunctionTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_library.cpp b/test/goalc/test_library.cpp new file mode 100644 index 0000000000..ea18da0fc5 --- /dev/null +++ b/test/goalc/test_library.cpp @@ -0,0 +1,70 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct LibraryParam { + // TODO - Not Needed Yet +}; + +class LibraryTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_logic.cpp b/test/goalc/test_logic.cpp new file mode 100644 index 0000000000..3aa4ed807b --- /dev/null +++ b/test/goalc/test_logic.cpp @@ -0,0 +1,68 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct LogicParam { + // TODO - Not Needed Yet +}; + +class LogicTests : public testing::TestWithParam { + 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"}); +} + \ No newline at end of file diff --git a/test/goalc/test_loop_recur.cpp b/test/goalc/test_loop_recur.cpp new file mode 100644 index 0000000000..cc0a7b41fb --- /dev/null +++ b/test/goalc/test_loop_recur.cpp @@ -0,0 +1,66 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct LoopRecurParam { + // TODO - Not Needed Yet +}; + +class LoopRecurTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_macros.cpp b/test/goalc/test_macros.cpp new file mode 100644 index 0000000000..ffe0397542 --- /dev/null +++ b/test/goalc/test_macros.cpp @@ -0,0 +1,65 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct MacroParam { + // TODO - Not Needed Yet +}; + +class MacroTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_methods.cpp b/test/goalc/test_methods.cpp new file mode 100644 index 0000000000..92b52faaa8 --- /dev/null +++ b/test/goalc/test_methods.cpp @@ -0,0 +1,61 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct MethodParam { + // TODO - Not Needed Yet +}; + +class MethodTests : public testing::TestWithParam { + 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"}); +} \ No newline at end of file diff --git a/test/goalc/test_pointers.cpp b/test/goalc/test_pointers.cpp new file mode 100644 index 0000000000..a42c753db1 --- /dev/null +++ b/test/goalc/test_pointers.cpp @@ -0,0 +1,65 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct PointerParam { + // TODO - Not Needed Yet +}; + +class PointerTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_strings.cpp b/test/goalc/test_strings.cpp new file mode 100644 index 0000000000..fddbff44d0 --- /dev/null +++ b/test/goalc/test_strings.cpp @@ -0,0 +1,88 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct StringParam { + // TODO - Not Needed Yet +}; + +class StringTests : public testing::TestWithParam { + 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 #\n"; +// +// expected += "test S a string a-symbol another string!\n"; +// expected += "test C ) ]\n"; +// expected += "test P (no type) #\n"; +// expected += "test P (with type) 1447236\n"; +// +// // todo, finish format testing. +// runner.run_test("test-format.gc", {expected}, expected.size()); diff --git a/test/goalc/test_symbols.cpp b/test/goalc/test_symbols.cpp new file mode 100644 index 0000000000..198804d614 --- /dev/null +++ b/test/goalc/test_symbols.cpp @@ -0,0 +1,64 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct SymbolParam { + // TODO - Not Needed Yet +}; + +class SymbolTests : public testing::TestWithParam { + 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 +} diff --git a/test/goalc/test_variables.cpp b/test/goalc/test_variables.cpp new file mode 100644 index 0000000000..88a1b46510 --- /dev/null +++ b/test/goalc/test_variables.cpp @@ -0,0 +1,72 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct VariableParam { + // TODO - Not Needed Yet +}; + +class VariableTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp new file mode 100644 index 0000000000..41e54810d0 --- /dev/null +++ b/test/goalc/test_with_game.cpp @@ -0,0 +1,116 @@ +#include +#include + +#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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +struct WithGameParam { + // TODO - Not Needed Yet +}; + +class WithGameTests : public testing::TestWithParam { + 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"}); +} diff --git a/test/test_compiler_and_runtime.cpp b/test/test_compiler_and_runtime.cpp index 47d0cf4ea7..9033aa9994 100644 --- a/test/test_compiler_and_runtime.cpp +++ b/test/test_compiler_and_runtime.cpp @@ -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 expected, actual; - std::string test_name; - bool auto_pass = false; - }; - - std::vector tests; - - void run_test(const std::string& test_file, - const std::vector& expected, - MatchParam 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 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(argv)); -} - -void runtime_with_kernel() { - constexpr int argc = 3; - const char* argv[argc] = {"", "-fakeiso", "-debug"}; - exec_runtime(argc, const_cast(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 #\n"; - // - // expected += "test S a string a-symbol another string!\n"; - // expected += "test C ) ]\n"; - // expected += "test P (no type) #\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(); -}