Cmockery macro demo hacking

/*********************************************************************
 *                 Cmockery macro demo hacking
 * 说明:
 *     本文记录对Cmockery的宏使用的示例进行测试、跟踪。
 *
 *                                2016-5-7 深圳 南山平山村 曾剑锋
 ********************************************************************/

一、cat src/example/assert_macro.c
    /*
     * Copyright 2008 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    #include <string.h>

    static const char* status_code_strings[] = {
        "Address not found",
        "Connection dropped",
        "Connection timed out",
    };

    const char* get_status_code_string(const unsigned int status_code) {
        return status_code_strings[status_code];
    };

    unsigned int string_to_status_code(const char* const status_code_string) {
        unsigned int i;
        for (i = 0; i < sizeof(status_code_strings) /
                        sizeof(status_code_strings[0]); i++) {
            if (strcmp(status_code_strings[i], status_code_string) == 0) {
                return i;
            }
        }
        return ~0U;
    }

二、cat src/example/assert_macro_test.c
    /*
     * Copyright 2008 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    #include <stdarg.h>
    #include <stddef.h>
    #include <setjmp.h>
    #include <cmockery.h>

    extern const char* get_status_code_string(const unsigned int status_code);
    extern unsigned int string_to_status_code(
        const char* const status_code_string);

    /* This test will fail since the string returned by get_status_code_string(0)
     * doesn't match "Connection timed out". */
    void get_status_code_string_test(void **state) {
        assert_string_equal(get_status_code_string(0), "Address not found");        --+
        assert_string_equal(get_status_code_string(1), "Connection timed out");       |
    }                                                                                 |
                                                                                      |
    // This test will fail since the status code of "Connection timed out" isn't 1    |
    void string_to_status_code_test(void **state) {                                   |
        assert_int_equal(string_to_status_code("Address not found"), 0);            --*-+
        assert_int_equal(string_to_status_code("Connection timed out"), 1);           | |
    }                                                                                 | |
                                                                                      | |
    int main(int argc, char *argv[]) {                                                | |
        const UnitTest tests[] = {                                                    | |
            unit_test(get_status_code_string_test),                                   | |
            unit_test(string_to_status_code_test),                                    | |
        };                                                                            | |
        return run_tests(tests);                                                      | |
    }                                                                                 | |
                                                                                      | |
三、macro hacking                                                                     | |
                                                                                      | |
    // Assert that the two given strings are equal, otherwise fail.                   | |
    #define assert_string_equal(a, b) \                                         <-----+ |
        _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \    ------+ |
                             __LINE__)                                                | |
                                                                                      | |
    void _assert_string_equal(const char * const a, const char * const b,       <-----+ |
                              const char * const file, const int line) {                |
        if (!string_equal_display_error(a, b)) {                                ------+ |
            _fail(file, line);                                                        | |
        }                                                                             | |
    }                                                                                 | |
                                                                                      | |
    /* Determine whether the specified strings are equal.  If the strings are equal   | |
     * 1 is returned.  If they're not equal an error is displayed and 0 is            | |
     * returned. */                                                                   | |
    static int string_equal_display_error(                                      <-----+ |
            const char * const left, const char * const right) {                ------+ |
        if (strcmp(left, right) == 0) {                                               | |
            return 1;                                                                 | |
        }                                                                             | |
        print_error("\"%s\" != \"%s\"\n", left, right);                               | |
        return 0;                                                                     | |
    }                                                                                 | |
                                                                                      | |
    // Assert that the two given integers are equal, otherwise fail.                  | |
    #define assert_int_equal(a, b) \                                        <---------*-+
        _assert_int_equal(cast_to_largest_integral_type(a), \               ------+   |
                          cast_to_largest_integral_type(b), \                     |   |
                          __FILE__, __LINE__)                                     |   |
                                                                                  |   |
    void _assert_int_equal(                                                 <-----+   |
            const LargestIntegralType a, const LargestIntegralType b,                 |
            const char * const file, const int line) {                                |
        if (!values_equal_display_error(a, b)) {                            ----------+
            _fail(file, line);                                              ----------*-+
        }                                                                             | |
    }                                                                                 | |
                                                                                      | |
    /* Returns 1 if the specified values are equal.  If the values are not equal      | |
     * an error is displayed and 0 is returned. */                                    | |
    static int values_equal_display_error(const LargestIntegralType left,             | |
                                          const LargestIntegralType right) {          | |
        const int equal = left == right;                                              | |
        if (!equal) {                                                                 | |
            print_error(LargestIntegralTypePrintfFormat " != "                        | |
                        LargestIntegralTypePrintfFormat "\n", left, right);           | |
        }                                                                             | |
        return equal;                                                                 | |
    }                                                                                 | |
                                                                                      | |
    void print_error(const char* const format, ...) {                         <-------+ |
        va_list args;                                                                   |
        va_start(args, format);                                                         |
        vprint_error(format, args);                                           --------+ |
        va_end(args);                                                                 | |
    }                                                                                 | |
                                                                                      | |
    void vprint_error(const char* const format, va_list args) {               <-------+ |
        char buffer[1024];                                                              |
        vsnprintf(buffer, sizeof(buffer), format, args);                                |
        fprintf(stderr, buffer);                                                        |
    #ifdef _WIN32                                                                       |
        OutputDebugString(buffer);                                                      |
    #endif // _WIN32                                                                    |
    }                                                                                   |
                                                                                        |
    void _fail(const char * const file, const int line) {                      <--------+
        print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line);
        exit_test(1);                                                          --------+
    }                                                                                  |
                                                                                       |
    // Exit the currently executing test.                                              |
    static void exit_test(const int quit_application) {                         <------+
        if (global_running_test) {
            longjmp(global_run_test_env, 1);
        } else if (quit_application) {
            exit(-1);
        }
    }

四、运行结果:
    myzr@myzr:~/c_program/cmockery-master/src/example$ gcc assert_macro* -lcmockery
    myzr@myzr:~/c_program/cmockery-master/src/example$ ./a.out
    get_status_code_string_test: Starting test
    "Connection dropped" != "Connection timed out"
    ERROR: assert_macro_test.c:29 Failure!
    get_status_code_string_test: Test failed.
    string_to_status_code_test: Starting test
    2 != 1
    ERROR: assert_macro_test.c:35 Failure!
    string_to_status_code_test: Test failed.
    2 out of 2 tests failed!
        get_status_code_string_test
        string_to_status_code_test
    myzr@myzr:~/c_program/cmockery-master/src/example$ 

 

posted on 2016-05-07 14:27  zengjf  阅读(277)  评论(0编辑  收藏  举报

导航