From 7d5168ab05558d1ad04eb7aec4cbd2ad3aea81fe Mon Sep 17 00:00:00 2001 From: yuyawk <46620009+yuyawk@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:53:19 +0900 Subject: [PATCH] Unit test (#27) --- .github/workflows/tests.yml | 23 ++++ development/clang_tools/.clang-tidy | 3 + development/cli/run_unit_test.bash | 12 ++ libc_replacer/cc/internal/BUILD.bazel | 5 +- .../cc/internal/unit_test/BUILD.bazel | 15 +++ .../cc/internal/unit_test/macro_impl_test.c | 122 ++++++++++++++++++ 6 files changed, 179 insertions(+), 1 deletion(-) create mode 100755 development/cli/run_unit_test.bash create mode 100644 libc_replacer/cc/internal/unit_test/BUILD.bazel create mode 100644 libc_replacer/cc/internal/unit_test/macro_impl_test.c diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4982388..7b04717 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,6 +13,28 @@ concurrency: cancel-in-progress: true jobs: + unit-test: + strategy: + matrix: + bazel-version: + - 7.x + runner: + - ubuntu-20.04 + - ubuntu-22.04 + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + - name: Set up + uses: ./.github/actions/setup + with: + bazel-version: ${{ matrix.bazel-version }} + - name: Unit test + shell: bash + run: ./development/cli/run_unit_test.bash + integration-test: strategy: matrix: @@ -69,6 +91,7 @@ jobs: all-tests-passable: if: always() needs: + - unit-test - integration-test - style-check runs-on: ubuntu-latest diff --git a/development/clang_tools/.clang-tidy b/development/clang_tools/.clang-tidy index aa6015e..27b156b 100644 --- a/development/clang_tools/.clang-tidy +++ b/development/clang_tools/.clang-tidy @@ -14,3 +14,6 @@ Checks: " -cert-dcl51-cpp, " WarningsAsErrors: "*" +CheckOptions: + - key: readability-function-cognitive-complexity.IgnoreMacros + value: true diff --git a/development/cli/run_unit_test.bash b/development/cli/run_unit_test.bash new file mode 100755 index 0000000..bdab02b --- /dev/null +++ b/development/cli/run_unit_test.bash @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# +# Run integration tests. + +set -euo pipefail + +SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) +source "${SCRIPT_DIR}/common.bash" + +cd "${REPO_ROOT_DIR}" + +"${BAZEL_EXECUTABLE[@]}" test //... diff --git a/libc_replacer/cc/internal/BUILD.bazel b/libc_replacer/cc/internal/BUILD.bazel index c4743b1..d0b08f0 100644 --- a/libc_replacer/cc/internal/BUILD.bazel +++ b/libc_replacer/cc/internal/BUILD.bazel @@ -8,5 +8,8 @@ cc_library( "definition_helper.h", "macro_impl.h", ], - visibility = ["//libc_replacer/cc:__subpackages__"], + visibility = [ + "//libc_replacer/cc:__subpackages__", + "//libc_replacer/cc/internal/unit_test:__pkg__", + ], ) diff --git a/libc_replacer/cc/internal/unit_test/BUILD.bazel b/libc_replacer/cc/internal/unit_test/BUILD.bazel new file mode 100644 index 0000000..091d70a --- /dev/null +++ b/libc_replacer/cc/internal/unit_test/BUILD.bazel @@ -0,0 +1,15 @@ +"""Unit tests for `//libc_replacer/cc/internal`. +""" + +cc_test( + name = "unit_test", + timeout = "short", + srcs = [ + "macro_impl_test.c", + ], + features = ["fully_static_link"], + linkstatic = True, + deps = [ + "//libc_replacer/cc/internal", + ], +) diff --git a/libc_replacer/cc/internal/unit_test/macro_impl_test.c b/libc_replacer/cc/internal/unit_test/macro_impl_test.c new file mode 100644 index 0000000..d16ae06 --- /dev/null +++ b/libc_replacer/cc/internal/unit_test/macro_impl_test.c @@ -0,0 +1,122 @@ +#include "libc_replacer/cc/internal/macro_impl.h" +#include +#include +#include + +// Test utility functions +#define TEST_ASSERT_TOKEN_EQ_IMPL(lhs, rhs, expected_equal) \ + do { \ + if ((strcmp(#lhs, #rhs) == 0) != (expected_equal)) { \ + if (expected_equal) { \ + int discarded = fputs("TEST_ASSERT_TOKEN_EQ failed: '" #lhs \ + " == " #rhs "' is not satisfied.\n", \ + stderr); \ + (void)discarded; \ + } else { \ + int discarded = fputs("TEST_ASSERT_TOKEN_NE failed: '" #lhs \ + " != " #rhs "' is not satisfied.\n", \ + stderr); \ + (void)discarded; \ + } \ + int fail = 0; \ + assert(fail); \ + } \ + } while (0) +#define TEST_ASSERT_TOKEN_EQ(lhs, rhs) TEST_ASSERT_TOKEN_EQ_IMPL(lhs, rhs, 1) +#define TEST_ASSERT_TOKEN_NE(lhs, rhs) TEST_ASSERT_TOKEN_EQ_IMPL(lhs, rhs, 0) + +// For testing `LIBC_REPLACER_INTERNAL_APPLY` +#define ADD_FOO(arg) FOO##arg + +int main(void) { + // Test LIBC_REPLACER_INTERNAL_GET_TYPE_FROM_TWO_ELEMENTS + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_GET_TYPE_FROM_TWO_ELEMENTS(int, param), int); + + // Test LIBC_REPLACER_INTERNAL_GET_NAME_FROM_TWO_ELEMENTS + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_GET_NAME_FROM_TWO_ELEMENTS(int, param), param); + + // Test LIBC_REPLACER_INTERNAL_GET_TYPE_AND_NAME_FROM_TWO_ELEMENTS + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_GET_TYPE_AND_NAME_FROM_TWO_ELEMENTS(int, param), + int param); + + // Test LIBC_REPLACER_INTERNAL_GET_ARG_TYPE_FROM_TUPLE + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_GET_ARG_TYPE_FROM_TUPLE((int, param)), int); + + // Test LIBC_REPLACER_INTERNAL_GET_ARG_NAME_FROM_TUPLE + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_GET_ARG_NAME_FROM_TUPLE((int, param)), param); + + // Test LIBC_REPLACER_INTERNAL_GET_ARG_TYPE_AND_NAME_FROM_TUPLE + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_GET_ARG_TYPE_AND_NAME_FROM_TUPLE((int, param)), + int param); + + // Test LIBC_REPLACER_INTERNAL_COUNT + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_COUNT(one), 1); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_COUNT(one, two), 2); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_COUNT(one, two, three), 3); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_COUNT(one, two, three, four), 4); + TEST_ASSERT_TOKEN_EQ( + LIBC_REPLACER_INTERNAL_COUNT(one, two, three, four, five), 5); + + // Test LIBC_REPLACER_INTERNAL_APPLY + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_APPLY(ADD_FOO, one), FOOone); + TEST_ASSERT_TOKEN_EQ((LIBC_REPLACER_INTERNAL_APPLY(ADD_FOO, one, two)), + (FOOone, FOOtwo)); + TEST_ASSERT_TOKEN_EQ((LIBC_REPLACER_INTERNAL_APPLY(ADD_FOO, one, two, three)), + (FOOone, FOOtwo, FOOthree)); + TEST_ASSERT_TOKEN_EQ( + (LIBC_REPLACER_INTERNAL_APPLY(ADD_FOO, one, two, three, four)), + (FOOone, FOOtwo, FOOthree, FOOfour)); + TEST_ASSERT_TOKEN_EQ( + (LIBC_REPLACER_INTERNAL_APPLY(ADD_FOO, one, two, three, four, five)), + (FOOone, FOOtwo, FOOthree, FOOfour, FOOfive)); + + // Test LIBC_REPLACER_INTERNAL_GET_ARG_TYPES + TEST_ASSERT_TOKEN_EQ((LIBC_REPLACER_INTERNAL_GET_ARG_TYPES( + (int, foo), (void, ), (float, bar))), + (int, void, float)); + + // Test LIBC_REPLACER_INTERNAL_GET_ARG_NAMES + TEST_ASSERT_TOKEN_EQ((LIBC_REPLACER_INTERNAL_GET_ARG_NAMES( + (int, foo), (void, ), (float, bar))), + (foo, , bar)); + + // Test LIBC_REPLACER_INTERNAL_GET_ARG_TYPES_AND_NAMES + // clang-format off + TEST_ASSERT_TOKEN_EQ((LIBC_REPLACER_INTERNAL_GET_ARG_TYPES_AND_NAMES( + (int, foo), (void, ), (float, bar))), + (int foo, void , float bar)); + // clang-format on + + // Test LIBC_REPLACER_INTERNAL_CONCATENATE + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_CONCATENATE(foo, bar), foobar); + + // Test LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(int), return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(float), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(double), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(time_t), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void), ); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void_t), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void *), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void **), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void ***), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void ****), + return); + TEST_ASSERT_TOKEN_EQ(LIBC_REPLACER_INTERNAL_RETURN_IF_NOT_VOID(void *****), + return); + + return 0; +}