int _main()

in include/poac/subcmd/test.hpp [22:136]


        int _main(VS&& argv) {
            namespace fs = boost::filesystem;
            namespace exception = core::exception;

            const auto node = io::file::yaml::load_config("test");
            const bool verbose = util::argparse::use(argv, "-v", "--verbose");

            const bool usemain = false;

            stroite::builder bs;
            bs.configure_compile(usemain, verbose);

            // You can use #include<> in test code.
            bs.compile_conf.include_search_path.push_back((fs::current_path() / "include").string());

            std::string static_link_lib;
            if (const auto test_framework = io::file::yaml::get<std::string>(node.at("test"), "framework")) {
                if (*test_framework == "boost") {
                    static_link_lib = "boost_unit_test_framework";
                }
                else if (*test_framework == "google") {
                    // TODO: select
                    static_link_lib = "gtest";
//                    static_link_lib = "gtest_main";
                }
                else {
                    throw exception::error("Invalid test framework");
                }
            }

            for (const fs::path &p : fs::recursive_directory_iterator(fs::current_path() / "test")) {
                if (!fs::is_directory(p) && p.extension().string() == ".cpp") {
                    const std::string cpp_relative = fs::relative(p).string();
                    const std::string bin_name = fs::path(
                            boost::replace_all_copy(
                                    fs::relative(cpp_relative, "test").string(), "/", "-")).stem().string();
                    const std::string bin_path = (io::file::path::current_build_test_bin_dir / bin_name).string();

                    bs.compile_conf.source_files = bs.hash_source_files({cpp_relative}, usemain);
                    if (bs.compile_conf.source_files.empty()) { // No need for compile and link
                        std::cout << io::cli::yellow << "Warning: " << io::cli::reset
                                  << "There is no change. Binary exists in `" +
                                     fs::relative(bin_path).string() + "`."
                                  << std::endl;
//                        continue;
                    }
                    else {
                        if (const auto obj_files_path = bs._compile()) {
                            bs.configure_link(*obj_files_path, verbose);
                            bs.link_conf.project_name = bin_name;
                            bs.link_conf.output_root = io::file::path::current_build_test_bin_dir;
                            bs.link_conf.static_link_libs.push_back(static_link_lib);
                            if (bs._link()) {
                                std::cout << io::cli::green << "Compiled: " << io::cli::reset
                                          << "Output to `" +
                                             fs::relative(bin_path).string() +
                                             "`"
                                          << std::endl;
                            }
                            else { // Link failure
                                continue;
                            }
                        }
                        else { // Compile failure
                            continue;
                        }
                    }

                    //
                    // execute binary
                    //
                    util::command cmd(fs::relative(bin_path).string());
                    // poac test -v -- -h build
                    if (const auto result = std::find(argv.begin(), argv.end(), "--"); result != argv.end()) {
                        // -h build
                        std::vector<std::string> test_args(result + 1, argv.end());
                        for (const auto &s : test_args) {
                            cmd += s;
                        }
                    }
                    else if (const auto test_args = io::file::yaml::get<std::vector<std::string>>(
                            node.at("test"), "args"))
                    {
                        for (const auto &s : *test_args) {
                            cmd += s;
                        }
                    }
                    if (util::argparse::use(argv, "--report")) {
                        fs::create_directories(io::file::path::current_build_test_report_dir);
                        cmd += ">";
                        cmd += (io::file::path::current_build_test_report_dir / bin_name).string() + ".xml";
                    }
                    else if (const auto test_report = io::file::yaml::get<bool>(node.at("test"), "report")) {
                        if (*test_report) {
                            fs::create_directories(io::file::path::current_build_test_report_dir);
                            cmd += ">";
                            cmd += (io::file::path::current_build_test_report_dir / bin_name).string() + ".xml";
                        }
                    }
                    // TODO: echo => Output .xml ...

                    std::cout << io::cli::green << "Running: " << io::cli::reset
                              << "`" + fs::relative(bin_path).string() + "`"
                              << std::endl;
                    if (const auto ret = cmd.exec())
                        std::cout << *ret;
                    else
                        std::cout << std::endl
                                  << fs::relative(bin_path).string() + " returned 1" << std::endl;

                    std::cout << "----------------------------------------------------------------" << std::endl;
                }
            }
            return EXIT_SUCCESS;
        }