Home | History | Annotate | Download | only in test
      1 /******************************************************************************
      2  *
      3  *  Copyright 2014 Google, Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #pragma once
     20 
     21 // Helper macros for stubbing out functions and modules for testing.
     22 
     23 // Stub out a function, with call counting and mode awareness
     24 #define STUB_FUNCTION(ret, name, params)                 \
     25   UNUSED_ATTR static int name##_callcount;               \
     26   static ret name params {                               \
     27     UNUSED_ATTR int _local_callcount = name##_callcount; \
     28     name##_callcount++;
     29 
     30 // Expect a certain number of calls to the specified stub function
     31 #define EXPECT_CALL_COUNT(name, count)   \
     32   EXPECT_EQ((count), (name##_callcount)) \
     33       << "expected " #name " to be called " #count " times"
     34 
     35 // Reset the call count for the specificed stub function
     36 #define RESET_CALL_COUNT(name) ((name##_callcount) = 0)
     37 
     38 // Use this in a stub function to catch unexpected calls.
     39 // Prints out a nice message including the call count, the
     40 // stub function name, and the mode index (sadly no mode name)
     41 #define UNEXPECTED_CALL                                                  \
     42   EXPECT_TRUE(false) << "unexpected call " << _local_callcount << " to " \
     43                      << __func__ << " during mode " << (int)_current_mode
     44 
     45 #define MODE_IS(mode) (_current_mode == (mode))
     46 
     47 // Macro selection helpers
     48 #define OVERLOAD_CAT(A, B) A##B
     49 #define OVERLOAD_SELECT(NAME, NUM) OVERLOAD_CAT(NAME##_, NUM)
     50 #define OVERLOAD_GET_COUNT(_1, _2, _3, _4, _5, _6, COUNT, ...) COUNT
     51 #define OVERLOAD_VA_SIZE(...) OVERLOAD_GET_COUNT(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
     52 #define OVERLOAD_OF(NAME, ...) \
     53   OVERLOAD_SELECT(NAME, OVERLOAD_VA_SIZE(__VA_ARGS__))(__VA_ARGS__)
     54 
     55 // Use this to branch stub function execution to a specific mode or modes.
     56 // Treat it like an if statement. For example:
     57 //
     58 // DURING(dinner) EXPECT_EQ(bread_pudding, food);
     59 // DURING(midday_snack, midnight_snack) EXPECT_EQ(chocolate, food);
     60 #define DURING(...) OVERLOAD_OF(DURING, __VA_ARGS__)
     61 
     62 #define DURING_1(mode0) if (MODE_IS(mode0))
     63 #define DURING_2(mode0, mode1) if (MODE_IS(mode0) || MODE_IS(mode1))
     64 #define DURING_3(mode0, mode1, mode2) \
     65   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2))
     66 #define DURING_4(mode0, mode1, mode2, mode3) \
     67   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3))
     68 #define DURING_5(mode0, mode1, mode2, mode3, mode4)                           \
     69   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3) || \
     70       MODE_IS(mode4))
     71 #define DURING_6(mode0, mode1, mode2, mode3, mode4, mode5)                    \
     72   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3) || \
     73       MODE_IS(mode4) || MODE_IS(mode5))
     74 
     75 // Use this to branch stub function exeuction to a specific call
     76 // count index (zero based). Treat it like an if statement.
     77 // Usually most helpful following a DURING clause. For example:
     78 //
     79 // DURING (breakfast) AT_CALL(0) EXPECT_EQ(bacon, food);
     80 //
     81 // or
     82 //
     83 // DURING (three_course_meal) {
     84 //   AT_CALL(0) EXPECT_EQ(shrimp_cocktail, food);
     85 //   AT_CALL(1) EXPECT_EQ(bacon_wrapped_bacon, food);
     86 //   AT_CALL(1) EXPECT_EQ(chocolate_covered_fake_blueberries, food);
     87 // }
     88 #define AT_CALL(index) if (_local_callcount == (index))
     89 
     90 // Declare all the available test modes for the DURING clauses
     91 // For example:
     92 //
     93 // DECLARE_TEST_MODES(breakfast, lunch, dinner);
     94 #define DECLARE_TEST_MODES(...)               \
     95   typedef enum { __VA_ARGS__ } _test_modes_t; \
     96   static _test_modes_t _current_mode;
     97 
     98 // Get the current test mode
     99 #define CURRENT_TEST_MODE _current_mode
    100 
    101 #define TEST_MODES_T _test_modes_t
    102