-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create more general Test Framework and Organize the bulk of current tests #67
Changes from all commits
282e53f
6634537
097a915
df6e6dd
83f2751
b99b63a
76bede1
f712c61
c34c0a8
6e1dea4
bf3344c
4429632
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
include("goalc/CMakeLists.txt") | ||
|
||
add_executable(goalc-test | ||
test_main.cpp | ||
test_test.cpp | ||
|
@@ -13,18 +17,17 @@ add_executable(goalc-test | |
test_emitter_xmm32.cpp | ||
test_emitter_integer_math.cpp | ||
test_common_util.cpp | ||
test_compiler_and_runtime.cpp | ||
test_deftype.cpp | ||
test_pretty_print.cpp | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this removed by accident? |
||
) | ||
${GOALC_TEST_FRAMEWORK_SOURCES} | ||
${GOALC_TEST_CASES}) | ||
|
||
enable_testing() | ||
|
||
IF (WIN32) | ||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) | ||
|
||
# TODO - split out these declarations for platform specific includes | ||
target_link_libraries(goalc-test cross_sockets listener mman goos common_util runtime compiler type_system gtest) | ||
target_link_libraries(goalc-test cross_sockets goos common_util listener runtime compiler type_system gtest mman) | ||
ELSE() | ||
target_link_libraries(goalc-test cross_sockets goos common_util listener runtime compiler type_system gtest) | ||
ENDIF() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# TODO - probably a more cmakey way to do this | ||
|
||
set(GOALC_TEST_CASES | ||
"goalc/test_arithmetic.cpp" | ||
"goalc/test_compiler.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" | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Some Documentation | ||
|
||
TODO! | ||
|
||
# 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? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
|
||
#include "test_runner.h" | ||
|
||
#include <string> | ||
|
||
#include "gtest/gtest.h" | ||
#include "third-party/inja.hpp" | ||
#include "third-party/json.hpp" | ||
|
||
#include "game/runtime.h" | ||
#include "goalc/listener/Listener.h" | ||
#include "goalc/compiler/Compiler.h" | ||
|
||
#include "common/util/FileUtil.h" | ||
#include <filesystem> | ||
|
||
namespace GoalTest { | ||
|
||
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; | ||
} | ||
|
||
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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't worry about changing this now, but C++17 now has |
||
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_category + "/" + test_file); | ||
if (!truncate.is_wildcard) { | ||
for (auto& x : result) { | ||
x = x.substr(0, truncate.value); | ||
} | ||
} | ||
|
||
bool assertionFailed = false; | ||
EXPECT_EQ(result, expected) << (assertionFailed = true); | ||
|
||
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); | ||
|
||
std::string testOutput = "\n\n;------TEST OUTPUT------\n;-------Expected-------\n"; | ||
|
||
for (auto& x : expected) { | ||
testOutput += fmt::format("; \"{}\"\n", escaped_string(x)); | ||
} | ||
testOutput += "\n;--------Actual--------\n"; | ||
for (auto& x : result) { | ||
testOutput += fmt::format("; \"{}\"\n", escaped_string(x)); | ||
} | ||
|
||
dst << src.rdbuf() << testOutput; | ||
} | ||
|
||
tests.push_back({expected, result, test_file, false}); | ||
} | ||
|
||
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}); | ||
} | ||
|
||
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)); | ||
} | ||
|
||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "third-party/inja.hpp" | ||
#include "goalc/compiler/Compiler.h" | ||
|
||
namespace GoalTest { | ||
|
||
std::string escaped_string(const std::string& in); | ||
|
||
struct CompilerTestRunner { | ||
public: | ||
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_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_category, const std::string& test_file); | ||
|
||
void print_summary(); | ||
}; | ||
|
||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.gc | ||
failed/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
; TODO this would be an easy function to templatize | ||
; but I'm not sure how to easily do it in test_arithmetic.cpp without repeating the fixture boilerplate | ||
|
||
(+ 15 -2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
; simply return an integer | ||
#x123456789 | ||
{{ integer }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
(define format _format) | ||
|
||
(let ((my-pair (cons 'a 'b))) | ||
(format #t "~A~A~%" (car my-pair) (cdr my-pair)) | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
(define format _format) | ||
|
||
(let ((my-pair (cons 'a 'b))) | ||
(set! (car my-pair) 'c) | ||
(set! (cdr my-pair) 'd) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
(define format _format) | ||
|
||
(format #t "~A~%" (cons 'a 'b)) | ||
0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(define format _format) | ||
|
||
(format #t "~A~%" '()) | ||
0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
(define format _format) | ||
|
||
(format #t "~A~%" (list 'a 'b 'c 'd)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
(define format _format) | ||
|
||
(format #t "~A~A~%" (pair? '()) (pair? integer)) | ||
0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
;; test the use of #cond to evaluate goos expressions at compile time | ||
|
||
(#cond | ||
((> 2 (+ 2 1)) | ||
1 | ||
(invalid-code) | ||
) | ||
|
||
((< 2 (+ 1 2)) | ||
3 | ||
) | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
(define format _format) | ||
|
||
(let ((x (if (> 1 2) "a string!")) | ||
(y (if (> 2 1) 123))) | ||
(if x | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
(define format _format) | ||
|
||
(defun float-testing-function ((x float) (y float)) | ||
(* x y (* x x)) | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea