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 #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