Home | History | Annotate | Download | only in test
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 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 // Helper macros for stubbing out functions and modules for testing.
     20 
     21 // Stub out a function, with call counting and mode awareness
     22 #define STUB_FUNCTION(ret, name, params) \
     23   UNUSED_ATTR static int name##_callcount; \
     24   static ret name params { \
     25     UNUSED_ATTR int _local_callcount = name##_callcount; \
     26     name##_callcount++;
     27 
     28 // Expect a certain number of calls to the specified stub function
     29 #define EXPECT_CALL_COUNT(name, count) \
     30   EXPECT_EQ((count), (name##_callcount)) << "expected " #name " to be called " #count " times"
     31 
     32 // Reset the call count for the specificed stub function
     33 #define RESET_CALL_COUNT(name) ((name##_callcount) = 0)
     34 
     35 // Use this in a stub function to catch unexpected calls.
     36 // Prints out a nice message including the call count, the
     37 // stub function name, and the mode index (sadly no mode name)
     38 #define UNEXPECTED_CALL EXPECT_TRUE(false) \
     39   << "unexpected call " << _local_callcount \
     40   << " to " << __func__ \
     41   << " during mode " << (int)_current_mode
     42 
     43 #define MODE_IS(mode) (_current_mode == (mode))
     44 
     45 // Macro selection helpers
     46 #define OVERLOAD_CAT(A, B) A##B
     47 #define OVERLOAD_SELECT(NAME, NUM) OVERLOAD_CAT(NAME##_, NUM)
     48 #define OVERLOAD_GET_COUNT(_1, _2, _3, _4, _5, _6, COUNT, ...) COUNT
     49 #define OVERLOAD_VA_SIZE(...) OVERLOAD_GET_COUNT(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
     50 #define OVERLOAD_OF(NAME, ...) OVERLOAD_SELECT(NAME, OVERLOAD_VA_SIZE(__VA_ARGS__))(__VA_ARGS__)
     51 
     52 // Use this to branch stub function execution to a specific mode or modes.
     53 // Treat it like an if statement. For example:
     54 //
     55 // DURING(dinner) EXPECT_EQ(bread_pudding, food);
     56 // DURING(midday_snack, midnight_snack) EXPECT_EQ(chocolate, food);
     57 #define DURING(...) OVERLOAD_OF(DURING, __VA_ARGS__)
     58 
     59 #define DURING_1(mode0) \
     60   if (MODE_IS(mode0))
     61 #define DURING_2(mode0, mode1) \
     62   if (MODE_IS(mode0) || MODE_IS(mode1))
     63 #define DURING_3(mode0, mode1, mode2) \
     64   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2))
     65 #define DURING_4(mode0, mode1, mode2, mode3) \
     66   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3))
     67 #define DURING_5(mode0, mode1, mode2, mode3, mode4) \
     68   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3) || MODE_IS(mode4))
     69 #define DURING_6(mode0, mode1, mode2, mode3, mode4, mode5) \
     70   if (MODE_IS(mode0) || MODE_IS(mode1) || MODE_IS(mode2) || MODE_IS(mode3) || MODE_IS(mode4) || MODE_IS(mode5))
     71 
     72 // Use this to branch stub function exeuction to a specific call
     73 // count index (zero based). Treat it like an if statement.
     74 // Usually most helpful following a DURING clause. For example:
     75 //
     76 // DURING (breakfast) AT_CALL(0) EXPECT_EQ(bacon, food);
     77 //
     78 // or
     79 //
     80 // DURING (three_course_meal) {
     81 //   AT_CALL(0) EXPECT_EQ(shrimp_cocktail, food);
     82 //   AT_CALL(1) EXPECT_EQ(bacon_wrapped_bacon, food);
     83 //   AT_CALL(1) EXPECT_EQ(chocolate_covered_fake_blueberries, food);
     84 // }
     85 #define AT_CALL(index) \
     86   if (_local_callcount == index)
     87 
     88 // Declare all the available test modes for the DURING clauses
     89 // For example:
     90 //
     91 // DECLARE_TEST_MODES(breakfast, lunch, dinner);
     92 #define DECLARE_TEST_MODES(...) \
     93   typedef enum { __VA_ARGS__ } _test_modes_t; \
     94   static _test_modes_t _current_mode;
     95 
     96 // Get the current test mode
     97 #define CURRENT_TEST_MODE _current_mode
     98 
     99 #define TEST_MODES_T _test_modes_t
    100