diff --git a/CMakeLists.txt b/CMakeLists.txt index f1c80245f18555d611b50cf72343a5caa529b7ea..15e785835218e2b6458fd307aaca50e441a55689 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ set(TEST_SOURCES "${CMAKE_SOURCE_DIR}/src/buffer.cpp" "${CMAKE_SOURCE_DIR}/src/util.cpp" "${CMAKE_SOURCE_DIR}/src/os.cpp" - "${CMAKE_SOURCE_DIR}/test/standalone.cpp" + "${CMAKE_SOURCE_DIR}/test/run_tests.cpp" ) diff --git a/test/run_tests.cpp b/test/run_tests.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a220e1251eb7e8067e2fa13e640accad9f92b2ef --- /dev/null +++ b/test/run_tests.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#include "list.hpp" +#include "buffer.hpp" +#include "os.hpp" + +#include + +struct TestSourceFile { + const char *relative_path; + const char *text; +}; + +struct TestCase { + const char *case_name; + const char *output; + const char *source; + ZigList compile_errors; + ZigList compiler_args; + ZigList program_args; +}; + +ZigList test_cases = {0}; +const char *tmp_source_path = ".tmp_source.zig"; +const char *tmp_exe_path = "./.tmp_exe"; + +static void add_simple_case(const char *case_name, const char *source, const char *output) { + TestCase *test_case = allocate(1); + test_case->case_name = case_name; + test_case->output = output; + test_case->source = source; + + test_case->compiler_args.append("build"); + test_case->compiler_args.append(tmp_source_path); + test_case->compiler_args.append("--output"); + test_case->compiler_args.append(tmp_exe_path); + test_case->compiler_args.append("--release"); + test_case->compiler_args.append("--strip"); + + test_cases.append(test_case); +} + +static void add_all_test_cases(void) { + add_simple_case("hello world with libc", R"SOURCE( + #link("c") + extern { + fn puts(s: *mut u8) -> i32; + fn exit(code: i32) -> unreachable; + } + + export fn _start() -> unreachable { + puts("Hello, world!"); + exit(0); + } + )SOURCE", "Hello, world!\n"); + + add_simple_case("function call", R"SOURCE( + #link("c") + extern { + fn puts(s: *mut u8) -> i32; + fn exit(code: i32) -> unreachable; + } + + fn empty_function_1() {} + fn empty_function_2() { return; } + + export fn _start() -> unreachable { + empty_function_1(); + empty_function_2(); + this_is_a_function(); + } + + fn this_is_a_function() -> unreachable { + puts("OK"); + exit(0); + } + )SOURCE", "OK\n"); + + add_simple_case("comments", R"SOURCE( + #link("c") + extern { + fn puts(s: *mut u8) -> i32; + fn exit(code: i32) -> unreachable; + } + + /** + * multi line doc comment + */ + fn another_function() {} + + /// this is a documentation comment + /// doc comment line 2 + export fn _start() -> unreachable { + puts(/* mid-line comment /* nested */ */ "OK"); + exit(0); + } + )SOURCE", "OK\n"); +} + +static void run_test(TestCase *test_case) { + os_write_file(buf_create_from_str(tmp_source_path), buf_create_from_str(test_case->source)); + + Buf zig_stderr = BUF_INIT; + Buf zig_stdout = BUF_INIT; + int return_code; + static const char *zig_exe = "./zig"; + os_exec_process(zig_exe, test_case->compiler_args, &return_code, &zig_stderr, &zig_stdout); + + if (return_code != 0) { + printf("\nCompile failed with return code %d:\n", return_code); + printf("%s", zig_exe); + for (int i = 0; i < test_case->compiler_args.length; i += 1) { + printf(" %s", test_case->compiler_args.at(i)); + } + printf("\n"); + printf("%s\n", buf_ptr(&zig_stderr)); + exit(1); + } + + Buf program_stderr = BUF_INIT; + Buf program_stdout = BUF_INIT; + os_exec_process(tmp_exe_path, test_case->program_args, &return_code, &program_stderr, &program_stdout); + + if (return_code != 0) { + printf("\nProgram exited with return code %d:\n", return_code); + printf("%s", tmp_exe_path); + for (int i = 0; i < test_case->program_args.length; i += 1) { + printf(" %s", test_case->program_args.at(i)); + } + printf("\n"); + printf("%s\n", buf_ptr(&program_stderr)); + exit(1); + } + + if (!buf_eql_str(&program_stdout, test_case->output)) { + printf("\n"); + printf("==== Test failed. Expected output: ====\n"); + printf("%s\n", test_case->output); + printf("========= Actual output: ==============\n"); + printf("%s\n", buf_ptr(&program_stdout)); + printf("=======================================\n"); + exit(1); + } +} + +static void run_all_tests(void) { + for (int i = 0; i < test_cases.length; i += 1) { + TestCase *test_case = test_cases.at(i); + printf("Test %d/%d %s...", i + 1, test_cases.length, test_case->case_name); + run_test(test_case); + printf("OK\n"); + } + printf("%d tests passed.\n", test_cases.length); +} + +static void cleanup(void) { + remove(tmp_source_path); + remove(tmp_exe_path); +} + +int main(int argc, char **argv) { + add_all_test_cases(); + run_all_tests(); + cleanup(); +} diff --git a/test/standalone.cpp b/test/standalone.cpp deleted file mode 100644 index a220e1251eb7e8067e2fa13e640accad9f92b2ef..0000000000000000000000000000000000000000 --- a/test/standalone.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of zig, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#include "list.hpp" -#include "buffer.hpp" -#include "os.hpp" - -#include - -struct TestSourceFile { - const char *relative_path; - const char *text; -}; - -struct TestCase { - const char *case_name; - const char *output; - const char *source; - ZigList compile_errors; - ZigList compiler_args; - ZigList program_args; -}; - -ZigList test_cases = {0}; -const char *tmp_source_path = ".tmp_source.zig"; -const char *tmp_exe_path = "./.tmp_exe"; - -static void add_simple_case(const char *case_name, const char *source, const char *output) { - TestCase *test_case = allocate(1); - test_case->case_name = case_name; - test_case->output = output; - test_case->source = source; - - test_case->compiler_args.append("build"); - test_case->compiler_args.append(tmp_source_path); - test_case->compiler_args.append("--output"); - test_case->compiler_args.append(tmp_exe_path); - test_case->compiler_args.append("--release"); - test_case->compiler_args.append("--strip"); - - test_cases.append(test_case); -} - -static void add_all_test_cases(void) { - add_simple_case("hello world with libc", R"SOURCE( - #link("c") - extern { - fn puts(s: *mut u8) -> i32; - fn exit(code: i32) -> unreachable; - } - - export fn _start() -> unreachable { - puts("Hello, world!"); - exit(0); - } - )SOURCE", "Hello, world!\n"); - - add_simple_case("function call", R"SOURCE( - #link("c") - extern { - fn puts(s: *mut u8) -> i32; - fn exit(code: i32) -> unreachable; - } - - fn empty_function_1() {} - fn empty_function_2() { return; } - - export fn _start() -> unreachable { - empty_function_1(); - empty_function_2(); - this_is_a_function(); - } - - fn this_is_a_function() -> unreachable { - puts("OK"); - exit(0); - } - )SOURCE", "OK\n"); - - add_simple_case("comments", R"SOURCE( - #link("c") - extern { - fn puts(s: *mut u8) -> i32; - fn exit(code: i32) -> unreachable; - } - - /** - * multi line doc comment - */ - fn another_function() {} - - /// this is a documentation comment - /// doc comment line 2 - export fn _start() -> unreachable { - puts(/* mid-line comment /* nested */ */ "OK"); - exit(0); - } - )SOURCE", "OK\n"); -} - -static void run_test(TestCase *test_case) { - os_write_file(buf_create_from_str(tmp_source_path), buf_create_from_str(test_case->source)); - - Buf zig_stderr = BUF_INIT; - Buf zig_stdout = BUF_INIT; - int return_code; - static const char *zig_exe = "./zig"; - os_exec_process(zig_exe, test_case->compiler_args, &return_code, &zig_stderr, &zig_stdout); - - if (return_code != 0) { - printf("\nCompile failed with return code %d:\n", return_code); - printf("%s", zig_exe); - for (int i = 0; i < test_case->compiler_args.length; i += 1) { - printf(" %s", test_case->compiler_args.at(i)); - } - printf("\n"); - printf("%s\n", buf_ptr(&zig_stderr)); - exit(1); - } - - Buf program_stderr = BUF_INIT; - Buf program_stdout = BUF_INIT; - os_exec_process(tmp_exe_path, test_case->program_args, &return_code, &program_stderr, &program_stdout); - - if (return_code != 0) { - printf("\nProgram exited with return code %d:\n", return_code); - printf("%s", tmp_exe_path); - for (int i = 0; i < test_case->program_args.length; i += 1) { - printf(" %s", test_case->program_args.at(i)); - } - printf("\n"); - printf("%s\n", buf_ptr(&program_stderr)); - exit(1); - } - - if (!buf_eql_str(&program_stdout, test_case->output)) { - printf("\n"); - printf("==== Test failed. Expected output: ====\n"); - printf("%s\n", test_case->output); - printf("========= Actual output: ==============\n"); - printf("%s\n", buf_ptr(&program_stdout)); - printf("=======================================\n"); - exit(1); - } -} - -static void run_all_tests(void) { - for (int i = 0; i < test_cases.length; i += 1) { - TestCase *test_case = test_cases.at(i); - printf("Test %d/%d %s...", i + 1, test_cases.length, test_case->case_name); - run_test(test_case); - printf("OK\n"); - } - printf("%d tests passed.\n", test_cases.length); -} - -static void cleanup(void) { - remove(tmp_source_path); - remove(tmp_exe_path); -} - -int main(int argc, char **argv) { - add_all_test_cases(); - run_all_tests(); - cleanup(); -}