diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93fcd58..eb386da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,4 +38,4 @@ jobs: run: ./build.py ${{ matrix.build.args }} - name: Test - run: ./build/bin/leetcode_test + run: ./build/bin/test_leetcode diff --git a/build.py b/build.py index 250c4f1..dfc1fa7 100755 --- a/build.py +++ b/build.py @@ -2,6 +2,7 @@ import os import sys import argparse +import subprocess parser = argparse.ArgumentParser(description='build') build_type_group = parser.add_mutually_exclusive_group() @@ -9,10 +10,23 @@ build_type_group.add_argument('-r', '--release', dest='build_type', action='store_const', const='Release') parser.set_defaults(build_type='Release') parser.add_argument('-a', '--asan', action='store_const', const='ON', default='OFF') +parser.add_argument('-j', '--jobs', type=int, default=os.cpu_count()) args = parser.parse_args() -cmake_args = f'-DCMAKE_BUILD_TYPE={args.build_type} ' +cmake_args = '' + +def has_ninja(): + try: + result = subprocess.run(['ninja', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return result.returncode == 0 + except Exception: + return False + +if has_ninja(): + cmake_args += '-G Ninja ' + +cmake_args += f'-DCMAKE_BUILD_TYPE={args.build_type} ' cmake_args += f'-DENABLE_ASAN={args.asan} ' def system_errexit(command: str): @@ -27,5 +41,6 @@ def system_errexit(command: str): if not os.path.exists('build'): os.mkdir('build') os.chdir('build') + system_errexit(f'cmake {cmake_args} ..') -system_errexit('cmake --build .') +system_errexit(f'cmake --build . -- -j{args.jobs}') diff --git a/leetcode/2011/solution.hpp b/leetcode/2011/solution.hpp index c754031..b296321 100644 --- a/leetcode/2011/solution.hpp +++ b/leetcode/2011/solution.hpp @@ -20,7 +20,7 @@ class Solution { }; } // namespace approach1 -// 方法2:++计数 +// 方法2:计数 namespace approach2 { class Solution { public: diff --git a/leetcode/CMakeLists.txt b/leetcode/CMakeLists.txt index 6385912..2e8b71f 100644 --- a/leetcode/CMakeLists.txt +++ b/leetcode/CMakeLists.txt @@ -1,9 +1,10 @@ # 构建测试对象库 file(GLOB_RECURSE TEST_SRC "*/test.cpp") -add_library(leetcode_test_o OBJECT ${TEST_SRC}) -target_include_directories(leetcode_test_o PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test) +add_library(test_leetcode_o OBJECT ${TEST_SRC}) +target_include_directories(test_leetcode_o PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test) +target_compile_definitions(test_leetcode_o PRIVATE PROBLEM_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}\") +target_compile_options(test_leetcode_o PRIVATE -Werror -Wall -Wextra -Wodr) # 构建测试二进制 -add_executable(leetcode_test) -target_compile_options(leetcode_test PRIVATE -Werror -Wall -Wextra -Wodr) -target_link_libraries(leetcode_test PRIVATE leetcode_test_o pthread gtest_main yaml-cpp) +add_executable(test_leetcode) +target_link_libraries(test_leetcode PRIVATE test_leetcode_o pthread gtest_main yaml-cpp) diff --git a/leetcode/test/test.cpp b/leetcode/test/test.cpp index 231c12c..49e0a0f 100644 --- a/leetcode/test/test.cpp +++ b/leetcode/test/test.cpp @@ -1,15 +1,19 @@ #include "test.hpp" +#include #include #include -std::string GetTestSuitePath(const char *file) { - std::filesystem::path path{file}; - return path.parent_path() / "test_suite.yaml"; +std::string GetTestSuitePath() { + std::filesystem::path path{PROBLEM_PATH}; + std::string_view suite{testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()}; + std::string_view num{ + suite.substr(std::distance(suite.begin(), std::find_if(suite.begin(), suite.end(), ::isdigit)))}; + return path / num / "test_suite.yaml"; } std::string GetTestCaseName() { std::string name{testing::UnitTest::GetInstance()->current_test_info()->name()}; - std::ranges::transform(name, name.begin(), [](unsigned char c) { return std::tolower(c); }); + name[0] = std::tolower(name[0]); return name; } diff --git a/leetcode/test/test.hpp b/leetcode/test/test.hpp index 0621b73..2fa8d3a 100644 --- a/leetcode/test/test.hpp +++ b/leetcode/test/test.hpp @@ -2,11 +2,10 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#define GET_TEST_CASE() ::GetTestCase(::GetTestSuitePath(__FILE__), ::GetTestCaseName()) #define TEST_Y(suite, name) \ - TEST(suite, name) { ::Expect(SolutionList{}, GET_TEST_CASE()); } + TEST(suite, name) { ::Expect(SolutionList{}, ::GetTestCase()); } -std::string GetTestSuitePath(const char *file); +std::string GetTestSuitePath(); std::string GetTestCaseName(); template @@ -21,11 +20,11 @@ auto GetTestSuite(const std::string &testSuitePath) { } template -const TestCase &GetTestCase(const std::string &testSuitePath, const std::string &key) { - static const std::string &path{testSuitePath}; +const TestCase &GetTestCase() { + static const auto path{GetTestSuitePath()}; static const auto testSuite{GetTestSuite(path)}; - assert(testSuitePath == path); - return testSuite.at(key); + assert(path == GetTestSuitePath()); + return testSuite.at(::GetTestCaseName()); } template