Run tests and check expectations in 2 loops
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
									
									
									
									
								
							@@ -12,5 +12,3 @@
 | 
				
			|||||||
- Syscalls.
 | 
					- Syscalls.
 | 
				
			||||||
- Error message with an empty file wrongly says that a ")" is expected.
 | 
					- Error message with an empty file wrongly says that a ")" is expected.
 | 
				
			||||||
- Support any expressions for constants.
 | 
					- Support any expressions for constants.
 | 
				
			||||||
- Built-in types are added in the symbol table constructor. It would be better to
 | 
					 | 
				
			||||||
  add them outside, before the type analysis begins.
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								cli/cl.cpp
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								cli/cl.cpp
									
									
									
									
									
								
							@@ -2,6 +2,7 @@
 | 
				
			|||||||
#include "elna/backend/target.hpp"
 | 
					#include "elna/backend/target.hpp"
 | 
				
			||||||
#include "elna/source/semantic.hpp"
 | 
					#include "elna/source/semantic.hpp"
 | 
				
			||||||
#include "elna/source/optimizer.hpp"
 | 
					#include "elna/source/optimizer.hpp"
 | 
				
			||||||
 | 
					#include "elna/source/types.hpp"
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace elna::cli
 | 
					namespace elna::cli
 | 
				
			||||||
@@ -13,6 +14,26 @@ namespace elna::cli
 | 
				
			|||||||
            << ": " << compile_error->what() << std::endl;
 | 
					            << ": " << compile_error->what() << std::endl;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static std::shared_ptr<source::symbol_table> add_builtin_symbols()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        source::symbol_table result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto boolean_info = std::make_shared<source::type_info>(source::boolean_type);
 | 
				
			||||||
 | 
					        auto int_info = std::make_shared<source::type_info>(source::int_type);
 | 
				
			||||||
 | 
					        result.enter("Boolean", boolean_info);
 | 
				
			||||||
 | 
					        result.enter("Int", int_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto writei = std::make_shared<source::intrinsic_info>();
 | 
				
			||||||
 | 
					        writei->parameter_infos.emplace_back(int_info->type());
 | 
				
			||||||
 | 
					        result.enter("writei", writei);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto writeb = std::make_shared<source::intrinsic_info>();
 | 
				
			||||||
 | 
					        writeb->parameter_infos.emplace_back(boolean_info->type());
 | 
				
			||||||
 | 
					        result.enter("writeb", writeb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return std::make_shared<source::symbol_table>(std::move(result));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int compile(const std::filesystem::path& in_file, const std::filesystem::path& out_file)
 | 
					    int compile(const std::filesystem::path& in_file, const std::filesystem::path& out_file)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
@@ -31,7 +52,7 @@ namespace elna::cli
 | 
				
			|||||||
                print_errors(parser.errors().cbegin(), parser.errors().cend());
 | 
					                print_errors(parser.errors().cbegin(), parser.errors().cend());
 | 
				
			||||||
                return 2;
 | 
					                return 2;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            auto global_scope = std::make_shared<source::symbol_table>();
 | 
					            auto global_scope = add_builtin_symbols();
 | 
				
			||||||
            source::name_analysis_visitor(global_scope).visit(ast.get());
 | 
					            source::name_analysis_visitor(global_scope).visit(ast.get());
 | 
				
			||||||
            source::type_analysis_visitor().visit(ast.get());
 | 
					            source::type_analysis_visitor().visit(ast.get());
 | 
				
			||||||
            source::allocator_visitor(global_scope).visit(ast.get());
 | 
					            source::allocator_visitor(global_scope).visit(ast.get());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,6 +204,9 @@ namespace elna::source
 | 
				
			|||||||
        std::string& identifier() noexcept;
 | 
					        std::string& identifier() noexcept;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Expression defining a composed type like pointer or an array.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    class type_expression : public node
 | 
					    class type_expression : public node
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::string m_base;
 | 
					        std::string m_base;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,13 +21,6 @@ namespace elna
 | 
				
			|||||||
        expectation_not_found
 | 
					        expectation_not_found
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct test_result final
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        test_status status{ test_status::successful };
 | 
					 | 
				
			||||||
        int code{ 0 };
 | 
					 | 
				
			||||||
        std::string output;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class test_results final
 | 
					    class test_results final
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::uint32_t m_total{ 0 };
 | 
					        std::uint32_t m_total{ 0 };
 | 
				
			||||||
@@ -46,10 +39,10 @@ namespace elna
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number,
 | 
					    boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number,
 | 
				
			||||||
            boost::asio::readable_pipe& read_pipe);
 | 
					            boost::asio::readable_pipe& read_pipe);
 | 
				
			||||||
    test_result run_for_output(boost::asio::io_context& context, const std::uint8_t stream_number,
 | 
					    int run_for_output(boost::asio::io_context& context, const std::uint8_t stream_number,
 | 
				
			||||||
            const std::filesystem::path& binary, std::initializer_list<boost::string_view> arguments);
 | 
					            const std::filesystem::path& binary, std::initializer_list<boost::string_view> arguments);
 | 
				
			||||||
    std::string find_object(const std::vector<std::filesystem::path>& environment, const std::string& object);
 | 
					    std::string find_object(const std::vector<std::filesystem::path>& environment, const std::string& object);
 | 
				
			||||||
    test_result build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry);
 | 
					    test_status build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry);
 | 
				
			||||||
    test_result run_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry);
 | 
					    void run_test(boost::asio::io_context& context, const std::filesystem::path& test_entry);
 | 
				
			||||||
    void print_result(const std::filesystem::directory_entry& test_entry, const test_result& result);
 | 
					    void print_result(const std::filesystem::path& test_entry, const test_status& result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,21 +6,6 @@ namespace elna::source
 | 
				
			|||||||
    symbol_table::symbol_table(std::shared_ptr<symbol_table> scope)
 | 
					    symbol_table::symbol_table(std::shared_ptr<symbol_table> scope)
 | 
				
			||||||
        : outer_scope(scope)
 | 
					        : outer_scope(scope)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (scope == nullptr)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            auto boolean_info = std::make_shared<type_info>(boolean_type);
 | 
					 | 
				
			||||||
            auto int_info = std::make_shared<type_info>(int_type);
 | 
					 | 
				
			||||||
            enter("Boolean", boolean_info);
 | 
					 | 
				
			||||||
            enter("Int", int_info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            auto writei = std::make_shared<intrinsic_info>();
 | 
					 | 
				
			||||||
            writei->parameter_infos.emplace_back(int_info->type());
 | 
					 | 
				
			||||||
            enter("writei", writei);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            auto writeb = std::make_shared<intrinsic_info>();
 | 
					 | 
				
			||||||
            writeb->parameter_infos.emplace_back(boolean_info->type());
 | 
					 | 
				
			||||||
            enter("writeb", writeb);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::shared_ptr<info> symbol_table::lookup(const std::string& name)
 | 
					    std::shared_ptr<info> symbol_table::lookup(const std::string& name)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										132
									
								
								tests/tester.cpp
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								tests/tester.cpp
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
#include "elna/tester.hpp"
 | 
					#include "elna/tester.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
#include <algorithm>
 | 
					#include <algorithm>
 | 
				
			||||||
#include <boost/process/env.hpp>
 | 
					#include <boost/process/env.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,6 +46,11 @@ namespace elna
 | 
				
			|||||||
        return in_build_directory() / path;
 | 
					        return in_build_directory() / path;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static std::filesystem::path in_actual_directory()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return "build/tests";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number,
 | 
					    boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number,
 | 
				
			||||||
            boost::asio::readable_pipe& read_pipe)
 | 
					            boost::asio::readable_pipe& read_pipe)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -59,19 +65,18 @@ namespace elna
 | 
				
			|||||||
        return boost::process::v2::process_stdio{ nullptr, read_pipe, read_pipe };
 | 
					        return boost::process::v2::process_stdio{ nullptr, read_pipe, read_pipe };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test_result run_for_output(boost::asio::io_context& context, const std::uint8_t stream_number,
 | 
					    int run_for_output(boost::asio::io_context& context, const std::filesystem::path& log_path,
 | 
				
			||||||
            const std::filesystem::path& binary, std::initializer_list<boost::string_view> arguments)
 | 
					            const std::filesystem::path& binary, std::initializer_list<boost::string_view> arguments)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        boost::asio::readable_pipe read_pipe{ context };
 | 
					        boost::asio::readable_pipe read_pipe{ context };
 | 
				
			||||||
        test_result result{};
 | 
					 | 
				
			||||||
        std::string output;
 | 
					        std::string output;
 | 
				
			||||||
        boost::asio::dynamic_string_buffer buffer = boost::asio::dynamic_buffer(output);
 | 
					        boost::asio::dynamic_string_buffer buffer = boost::asio::dynamic_buffer(output);
 | 
				
			||||||
        boost::system::error_code ec;
 | 
					        boost::system::error_code ec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        boost::process::v2::process_stdio process_stdio;
 | 
					        boost::process::v2::process_stdio process_stdio;
 | 
				
			||||||
        boost::process::v2::process elna_child(context,
 | 
					        boost::process::v2::process elna_child(context, binary, arguments,
 | 
				
			||||||
                binary, arguments,
 | 
					                boost::process::v2::process_stdio{ nullptr, read_pipe, 1 });
 | 
				
			||||||
                get_output_streams(stream_number, read_pipe));
 | 
					        std::ofstream log_file{ log_path };
 | 
				
			||||||
        do
 | 
					        do
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::size_t transferred = read_pipe.read_some(buffer.prepare(512), ec);
 | 
					            std::size_t transferred = read_pipe.read_some(buffer.prepare(512), ec);
 | 
				
			||||||
@@ -81,13 +86,12 @@ namespace elna
 | 
				
			|||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            buffer.commit(transferred);
 | 
					            buffer.commit(transferred);
 | 
				
			||||||
            result.output.append(boost::asio::buffer_cast<const char *>(buffer.data()), buffer.size());
 | 
					            log_file.write(boost::asio::buffer_cast<const char *>(buffer.data()), buffer.size());
 | 
				
			||||||
            buffer.consume(transferred);
 | 
					            buffer.consume(transferred);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        while (ec == boost::system::errc::success);
 | 
					        while (ec == boost::system::errc::success);
 | 
				
			||||||
        result.code = elna_child.wait();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return result;
 | 
					        return elna_child.wait();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string find_object(const std::vector<std::filesystem::path>& environment, const std::string& object)
 | 
					    std::string find_object(const std::vector<std::filesystem::path>& environment, const std::string& object)
 | 
				
			||||||
@@ -106,26 +110,27 @@ namespace elna
 | 
				
			|||||||
        return object;
 | 
					        return object;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test_result build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry)
 | 
					    test_status build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        const std::filesystem::path test_filename = test_entry.path().filename();
 | 
					        const std::filesystem::path test_filename = test_entry.path().filename();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::filesystem::path test_binary = in_build_directory(test_filename);
 | 
					        std::filesystem::path test_binary = in_build_directory(test_filename);
 | 
				
			||||||
        std::filesystem::path test_object = test_binary;
 | 
					        std::filesystem::path test_object = test_binary;
 | 
				
			||||||
 | 
					        std::filesystem::path test_log = test_binary;
 | 
				
			||||||
        test_binary.replace_extension();
 | 
					        test_binary.replace_extension();
 | 
				
			||||||
        test_object.replace_extension(".o");
 | 
					        test_object.replace_extension(".o");
 | 
				
			||||||
 | 
					        test_log.replace_extension(".log");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::filesystem::remove(test_binary);
 | 
					        std::filesystem::remove(test_binary);
 | 
				
			||||||
        std::filesystem::remove(test_object);
 | 
					        std::filesystem::remove(test_object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        test_result result = run_for_output(context, 2, "./build/bin/elna",
 | 
					        auto result_code = run_for_output(context, test_log, "./build/bin/elna",
 | 
				
			||||||
                { "-o", test_object.string(), test_entry.path().string() });
 | 
					                { "-o", test_object.string(), test_entry.path().string() });
 | 
				
			||||||
 | 
					        if (result_code != 0)
 | 
				
			||||||
        if (result.code != 0)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            result.status = test_status::compile_failed;
 | 
					            return test_status::compile_failed;
 | 
				
			||||||
            return result;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        test_status result = result_code == 0 ? test_status::successful : test_status::compile_failed;
 | 
				
			||||||
        std::vector<std::filesystem::path> environment;
 | 
					        std::vector<std::filesystem::path> environment;
 | 
				
			||||||
        std::vector<std::string> linker_arguments = { "-o", test_binary.string() };
 | 
					        std::vector<std::string> linker_arguments = { "-o", test_binary.string() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -141,64 +146,40 @@ namespace elna
 | 
				
			|||||||
                { "--start-group", "-lgcc", "-lc", "-lgloss", "--end-group" });
 | 
					                { "--start-group", "-lgcc", "-lc", "-lgloss", "--end-group" });
 | 
				
			||||||
        linker_arguments.push_back(find_object(environment, "crtend.o"));
 | 
					        linker_arguments.push_back(find_object(environment, "crtend.o"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        boost::process::v2::execute(boost::process::v2::process(context,
 | 
					        boost::process::v2::execute(boost::process::v2::process(context, boost::process::search_path("ld"),
 | 
				
			||||||
                    boost::process::search_path("ld"),
 | 
					 | 
				
			||||||
                    linker_arguments
 | 
					                    linker_arguments
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
        return test_result{};
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static test_result check_expectation(const std::filesystem::directory_entry& test_entry, const test_result& run)
 | 
					    static test_status check_expectation(const std::filesystem::path& expectation_path,
 | 
				
			||||||
 | 
					            const std::filesystem::path& actual_directory)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::filesystem::path test_filename = test_entry.path().filename();
 | 
					        std::filesystem::path log_filename = expectation_path.filename();
 | 
				
			||||||
        test_filename.replace_extension(".txt");
 | 
					        log_filename.replace_extension(".log");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const std::filesystem::path expectation_path =
 | 
					        std::filesystem::path test_log = actual_directory / log_filename;
 | 
				
			||||||
            test_entry.path().parent_path() / "expectations" / test_filename;
 | 
					 | 
				
			||||||
        const std::filesystem::path failures_path =
 | 
					 | 
				
			||||||
            test_entry.path().parent_path() / "failures" / test_filename;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string expected_result_path;
 | 
					        test_log.replace_extension(".log");
 | 
				
			||||||
        if (std::filesystem::exists(expectation_path))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            expected_result_path = expectation_path.string();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (std::filesystem::exists(failures_path))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            expected_result_path = failures_path.string();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return test_result{ test_status::expectation_not_found, run.code, run.output };
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        boost::process::opstream pipe_stream;
 | 
					 | 
				
			||||||
        boost::process::child diff(
 | 
					        boost::process::child diff(
 | 
				
			||||||
                boost::process::search_path("diff"), "-Nur", "--color",
 | 
					                boost::process::search_path("diff"), "-Nur", "--color",
 | 
				
			||||||
                expected_result_path, "-",
 | 
					                expectation_path, test_log
 | 
				
			||||||
                boost::process::std_in < pipe_stream
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					 | 
				
			||||||
        pipe_stream << run.output;
 | 
					 | 
				
			||||||
        pipe_stream.flush();
 | 
					 | 
				
			||||||
        pipe_stream.pipe().close();
 | 
					 | 
				
			||||||
        diff.wait();
 | 
					        diff.wait();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (diff.exit_code() == 0)
 | 
					        if (diff.exit_code() == 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return test_result{ test_status::successful, run.code, run.output };
 | 
					            return test_status::successful;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return test_result{ test_status::expectation_failed, run.code, run.output };
 | 
					        return test_status::expectation_failed;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test_result run_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry)
 | 
					    void run_test(boost::asio::io_context& context, const std::filesystem::path& test_binary)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        const std::filesystem::path test_filename = test_entry.path().filename();
 | 
					        std::filesystem::path test_log = test_binary;
 | 
				
			||||||
 | 
					        test_log.replace_extension(".log");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::filesystem::path test_binary = in_build_directory(test_filename);
 | 
					        run_for_output(context, test_log, boost::process::search_path("qemu-riscv32"),
 | 
				
			||||||
        test_binary.replace_extension();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return run_for_output(context, 1,
 | 
					 | 
				
			||||||
                boost::process::search_path("qemu-riscv32"),
 | 
					 | 
				
			||||||
                { test_binary.string() });
 | 
					                { test_binary.string() });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -213,33 +194,51 @@ namespace elna
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            test_result result;
 | 
					            test_status result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::cout << "Running " << test_entry << std::endl;
 | 
					            std::cout << "Running " << test_entry << std::endl;
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                result = build_test(context, test_entry);
 | 
					                build_test(context, test_entry);
 | 
				
			||||||
                if (result.status == test_status::successful)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    result = run_test(context, test_entry);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                result = check_expectation(test_entry, result);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (const boost::process::process_error& exception)
 | 
					            catch (const boost::process::process_error& exception)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                result.status = test_status::build_failed;
 | 
					                test_status::build_failed;
 | 
				
			||||||
                result.output = exception.what();
 | 
					                std::cout << exception.what() << std::endl;
 | 
				
			||||||
                std::cout << result.output << std::endl;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (const auto& executable_test : std::filesystem::directory_iterator(in_build_directory()))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (executable_test.path().has_extension())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            run_test(context, executable_test.path());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (const auto& expectation_entry : std::filesystem::directory_iterator(test_directory / "failures"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto test_entry = test_directory / expectation_entry.path().filename();
 | 
				
			||||||
 | 
					            test_entry.replace_extension(".eln");
 | 
				
			||||||
 | 
					            auto result = check_expectation(expectation_entry.path(), in_build_directory());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            print_result(test_entry, result);
 | 
					            print_result(test_entry, result);
 | 
				
			||||||
            results.add_exit_code(result.status);
 | 
					            results.add_exit_code(result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (const auto& expectation_entry : std::filesystem::directory_iterator(test_directory / "expectations"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            auto test_entry = test_directory / expectation_entry.path().filename();
 | 
				
			||||||
 | 
					            test_entry.replace_extension(".eln");
 | 
				
			||||||
 | 
					            auto result = check_expectation(expectation_entry.path(), in_actual_directory());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            print_result(test_entry, result);
 | 
				
			||||||
 | 
					            results.add_exit_code(result);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return results;
 | 
					        return results;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void print_result(const std::filesystem::directory_entry& test_entry, const test_result& result)
 | 
					    void print_result(const std::filesystem::path& test_entry, const test_status& result)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (result.status != test_status::successful)
 | 
					        if (result != test_status::successful)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::cout << test_entry << " failed." << std::endl;
 | 
					            std::cout << test_entry << " failed." << std::endl;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -249,6 +248,7 @@ namespace elna
 | 
				
			|||||||
int main()
 | 
					int main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    std::filesystem::create_directory(elna::in_build_directory());
 | 
					    std::filesystem::create_directory(elna::in_build_directory());
 | 
				
			||||||
 | 
					    std::filesystem::create_directory(elna::in_actual_directory());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::cout << "Run all tests and check the results" << std::endl;
 | 
					    std::cout << "Run all tests and check the results" << std::endl;
 | 
				
			||||||
    std::filesystem::path test_directory{ "tests" };
 | 
					    std::filesystem::path test_directory{ "tests" };
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user